home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / termMain.c < prev    next >
C/C++ Source or Header  |  1995-09-27  |  109KB  |  5,770 lines

  1. /*
  2. **    termMain.c
  3. **
  4. **    Program main routines and event loop
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Argument vectors offsets. */
  13.  
  14. enum    {    ARG_WINDOW,ARG_PUBSCREEN,ARG_STARTUP,ARG_PORTNAME,ARG_SETTINGS,ARG_UNIT,ARG_DEVICE,
  15.         ARG_NEW,ARG_SYNC,ARG_QUIET,ARG_BEHIND,ARG_DEBUG,ARG_LANGUAGE,ARG_PHONEBOOK,ARG_AUTODIAL,
  16.         ARG_AUTOEXIT,
  17.  
  18.         ARG_COUNT
  19.     };
  20.  
  21.     /* Argument template. */
  22.  
  23. #define ARGTEMPLATE    "WINDOW/K,PUBSCREEN/K,STARTUP/K,PORTNAME/K,SETTINGS/K,UNIT/K/N,DEVICE/K,NEW/S,SYNC/S,QUIET/S,BEHIND/S,DEBUG/S,LANGUAGE/K,PHONEBOOK/K,AUTODIAL/S,AUTOEXIT/S"
  24.  
  25.     /* Local config path variable. */
  26.  
  27. STATIC STRPTR        ConfigPath;
  28. STATIC UBYTE __far    ThePath[MAX_FILENAME_LENGTH];
  29.  
  30.     /* Local dialing list. */
  31.  
  32. STATIC struct List    *LocalDialList;
  33. STATIC LONG         LocalCount = -1;
  34.  
  35.     /* Startup file name. */
  36.  
  37. STATIC UBYTE __far    StartupFile[MAX_FILENAME_LENGTH];
  38.  
  39.     /* Did we hang up the line? */
  40.  
  41. STATIC BOOLEAN        HungUp = FALSE;
  42.  
  43.     // Go on redialing?
  44.  
  45. STATIC BOOLEAN        KeepRedialing = FALSE;
  46. STATIC BOOLEAN        AutoDial = FALSE;
  47. STATIC BOOLEAN        AutoExit = FALSE;
  48.  
  49.     /* Poll OwnDevUnit.library for the device to become available again? */
  50.  
  51. STATIC BOOLEAN        PollODU = FALSE;
  52. STATIC UWORD        PollODUCount = 0;
  53.  
  54.     /* Cloned CLI data. */
  55.  
  56. STATIC struct CommandLineInterface    *LocalCLI;
  57. STATIC BPTR                 OldCLI;
  58.  
  59.     /* Segment split routine, has to be local. */
  60.  
  61. STATIC struct Process * __regargs    SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function);
  62. STATIC VOID                CloseLibs(VOID);
  63.  
  64.     /* main():
  65.      *
  66.      *    This is our main entry point, check for the right
  67.      *    Kickstart version and fire off the background task
  68.      *    if approritate.
  69.      */
  70.  
  71. LONG
  72. main()
  73. {
  74.     STRPTR Result;
  75.  
  76.         /* Are we running as a child of Workbench? */
  77.  
  78.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  79.  
  80.     if(!ThisProcess -> pr_CLI)
  81.     {
  82.         WaitPort(&ThisProcess -> pr_MsgPort);
  83.  
  84.         WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess -> pr_MsgPort);
  85.     }
  86.     else
  87.         WBenchMsg = NULL;
  88.  
  89.         /* Now try to open dos.library and utility.library and go on examining
  90.          * our calling parameters.
  91.          */
  92.  
  93.     if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  94.     {
  95.         CloseLibs();
  96.  
  97.         return(RETURN_FAIL);
  98.     }
  99.  
  100.     if(!(UtilityBase = OpenLibrary("utility.library",0)))
  101.     {
  102.         CloseLibs();
  103.  
  104.         return(RETURN_FAIL);
  105.     }
  106.  
  107.         /* We were called from Shell. */
  108.  
  109.     if(ThisProcess -> pr_CLI)
  110.     {
  111.         STRPTR *ArgArray;
  112.  
  113.             /* Use the cute ReadArgs parser, allocate the
  114.              * argument vectors...
  115.              */
  116.  
  117.         if(ArgArray = (STRPTR *)AllocVec(sizeof(STRPTR) * (ARG_COUNT),MEMF_ANY|MEMF_CLEAR))
  118.         {
  119.             struct RDArgs *ArgsPtr;
  120.  
  121.             if(ArgsPtr = (struct RDArgs *)AllocDosObject(DOS_RDARGS,TAG_DONE))
  122.             {
  123.                 ArgsPtr -> RDA_ExtHelp =    "\nUsage: term [WINDOW <Name>] [PUBSCREEN <Name>] [STARTUP <File name>]\n"
  124.                                 "            [SETTINGS <File or path name>] [UNIT <Number>] [DEVICE <Name>]\n"
  125.                                 "            [NEW] [SYNC] [QUIET] [BEHIND] [LANGUAGE <Name>] [PHONEBOOK <File name>]\n"
  126.                                 "            [AUTODIAL] [AUTOEXIT]\n\n"
  127.                                 "     Window = Output window specifier\n"
  128.                                 "  PubScreen = Name of public screen to open window upon\n"
  129.                                 "    Startup = ARexx script file to run on startup\n"
  130.                                 "   Settings = Main configuration file name or path name to search for it\n"
  131.                                 "       Unit = Serial device driver unit number\n"
  132.                                 "     Device = Serial device driver name\n"
  133.                                 "        New = Spawn a new `term' process\n"
  134.                                 "       Sync = Keep links to Shell environment\n"
  135.                                 "      Quiet = Start iconified\n"
  136.                                 "     Behind = Open screen behind all other screens, don't activate the window\n"
  137.                                 "  Phonebook = Name of phonebook file to load\n"
  138.                                 "   Autodial = Dial phonebook entries which are marked for autodialing\n"
  139.                                 "   Autoexit = Exit `term' after dialing all autodial entries\n"
  140.                                 "   Language = Language to use for the user interface\n\n";
  141.  
  142.                     /* Parse the args (if any). */
  143.  
  144.                 if(ReadArgs(ARGTEMPLATE,(LONG *)ArgArray,ArgsPtr))
  145.                 {
  146.                         /* Pop a running `term' to the front? */
  147.  
  148.                     if((TermPort = (struct TermPort *)FindPort("term Port")) && !ArgArray[ARG_NEW])
  149.                     {
  150.                         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  151.                         {
  152.                             if(TermPort -> TopWindow)
  153.                                 BumpWindow(TermPort -> TopWindow);
  154.                         }
  155.  
  156.                         TermPort = NULL;
  157.  
  158.                         FreeArgs(ArgsPtr);
  159.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  160.                         FreeVec(ArgArray);
  161.  
  162.                         CloseLibs();
  163.  
  164.                         return(RETURN_OK);
  165.                     }
  166.  
  167.                     if(ArgArray[ARG_DEBUG])
  168.                         DebugFlag = TRUE;
  169.  
  170.                         /* Special language requested? */
  171.  
  172.                     if(ArgArray[ARG_LANGUAGE])
  173.                         strcpy(Language,ArgArray[ARG_LANGUAGE]);
  174.  
  175.                         /* Are we to use a special settings path? */
  176.  
  177.                     if(ArgArray[ARG_SETTINGS])
  178.                     {
  179.                         ConfigPath = ThePath;
  180.  
  181.                         strcpy(ThePath,ArgArray[ARG_SETTINGS]);
  182.                     }
  183.  
  184.                         /* Are we to use a special ARexx host port name? */
  185.  
  186.                     if(ArgArray[ARG_PORTNAME])
  187.                         strcpy(RexxPortName,ArgArray[ARG_PORTNAME]);
  188.  
  189.                         /* Are we to use a special output window name? */
  190.  
  191.                     if(ArgArray[ARG_WINDOW])
  192.                         strcpy(WindowName,ArgArray[ARG_WINDOW]);
  193.  
  194.                         /* Are we to run an ARexx script on startup? */
  195.  
  196.                     if(ArgArray[ARG_STARTUP])
  197.                         strcpy(StartupFile,ArgArray[ARG_STARTUP]);
  198.  
  199.                         // Load a special phonebook file
  200.  
  201.                     if(ArgArray[ARG_PHONEBOOK])
  202.                         strcpy(LastPhone,ArgArray[ARG_PHONEBOOK]);
  203.  
  204.                     if(ArgArray[ARG_AUTODIAL])
  205.                         AutoDial = TRUE;
  206.  
  207.                     if(ArgArray[ARG_AUTOEXIT])
  208.                         AutoExit = TRUE;
  209.  
  210.                         /* Are we to open a window on a public screen? */
  211.  
  212.                     if(ArgArray[ARG_PUBSCREEN])
  213.                         strcpy(SomePubScreenName,ArgArray[ARG_PUBSCREEN]);
  214.  
  215.                         /* Are we to use a special device? */
  216.  
  217.                     if(ArgArray[ARG_DEVICE])
  218.                     {
  219.                         strcpy(NewDevice,ArgArray[ARG_DEVICE]);
  220.  
  221.                         UseNewDevice = TRUE;
  222.                     }
  223.  
  224.                         /* Are we to use a special unit number? */
  225.  
  226.                     if(ArgArray[ARG_UNIT])
  227.                     {
  228.                         NewUnit = *(LONG *)ArgArray[ARG_UNIT];
  229.  
  230.                         UseNewUnit = TRUE;
  231.                     }
  232.  
  233.                         /* Are we to start up iconified? */
  234.  
  235.                     if(ArgArray[ARG_QUIET])
  236.                     {
  237.                         if(!StartupFile[0])
  238.                             DoIconify = TRUE;
  239.                     }
  240.  
  241.                         /* Hide the screen and don't activate the window? */
  242.  
  243.                     if(ArgArray[ARG_BEHIND])
  244.                         KeepQuiet = TRUE;
  245.  
  246.                         /* We are to keep our links to
  247.                          * the Shell.
  248.                          */
  249.  
  250.                     if(ArgArray[ARG_SYNC] || !ThisProcess -> pr_HomeDir)
  251.                     {
  252.                         BYTE OldPri = ThisProcess -> pr_Task . tc_Node . ln_Pri;
  253.  
  254.                             /* Open our resources and
  255.                              * squeak on failure.
  256.                              */
  257.  
  258.                         if(Result = OpenAll(ConfigPath))
  259.                         {
  260.                             if(Result[0])
  261.                                 Printf("\33[1mterm:\33[0m %s!\a\n",Result);
  262.  
  263.                             FreeArgs(ArgsPtr);
  264.                             FreeDosObject(DOS_RDARGS,ArgsPtr);
  265.                             FreeVec(ArgArray);
  266.  
  267.                             CloseAll(TRUE);
  268.  
  269.                             return(RETURN_FAIL);
  270.                         }
  271.  
  272.                             /* Go into main input
  273.                              * loop.
  274.                              */
  275.  
  276.                         if(StackSize(NULL) < 16384)
  277.                         {
  278.                             LONG Success;
  279.  
  280.                             StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  281.                         }
  282.                         else
  283.                             HandleInput();
  284.  
  285.                             /* Free the argument
  286.                              * data.
  287.                              */
  288.  
  289.                         FreeArgs(ArgsPtr);
  290.                         FreeDosObject(DOS_RDARGS,ArgsPtr);
  291.                         FreeVec(ArgArray);
  292.  
  293.                             /* Restore old priority. */
  294.  
  295.                         SetTaskPri(ThisProcess,(LONG)OldPri);
  296.  
  297.                             /* Terminate execution. */
  298.  
  299.                         CloseAll(TRUE);
  300.  
  301.                         return(RETURN_OK);
  302.                     }
  303.  
  304.                     FreeArgs(ArgsPtr);
  305.                 }
  306.                 else
  307.                 {
  308.                     PrintFault(IoErr(),"term");
  309.  
  310.                     FreeDosObject(DOS_RDARGS,ArgsPtr);
  311.                     FreeVec(ArgArray);
  312.  
  313.                     CloseLibs();
  314.  
  315.                     return(RETURN_ERROR);
  316.                 }
  317.  
  318.                 FreeDosObject(DOS_RDARGS,ArgsPtr);
  319.             }
  320.  
  321.             FreeVec(ArgArray);
  322.  
  323.                 /* Create a new process from our code. */
  324.  
  325.             if(!SegmentSplit("term main process",0,16384,HandleInput))
  326.             {
  327.                 Printf("\33[1mterm:\33[0m Failed to create new process!\a\n");
  328.  
  329.                 CloseLibs();
  330.  
  331.                 return(RETURN_FAIL);
  332.             }
  333.         }
  334.         else
  335.         {
  336.             Printf("\33[1mterm:\33[0m Failed to allocate argument vectors!\a\n");
  337.  
  338.             CloseLibs();
  339.  
  340.             return(RETURN_FAIL);
  341.         }
  342.     }
  343.     else
  344.     {
  345.             /* Try to create a local CLI structure so
  346.              * Shell commands will receive a valid
  347.              * search path list.
  348.              */
  349.  
  350.         if(LocalCLI = CloneCLI(&WBenchMsg -> sm_Message))
  351.         {
  352.             OldCLI = ThisProcess -> pr_CLI;
  353.  
  354.             ThisProcess -> pr_CLI = MKBADDR(LocalCLI);
  355.         }
  356.  
  357.         WBenchLock = CurrentDir(WBenchMsg -> sm_ArgList -> wa_Lock);
  358.  
  359.             /* Open icon.library, we want to take a
  360.              * look at the icon.
  361.              */
  362.  
  363.         if(IconBase = OpenLibrary("icon.library",0))
  364.         {
  365.             struct DiskObject *Icon;
  366.  
  367.                 /* Try to read the icon file. */
  368.  
  369.             if(Icon = GetProgramIcon())
  370.             {
  371.                 STRPTR Type;
  372.  
  373.                 if(FindToolType(Icon -> do_ToolTypes,"DEBUG"))
  374.                     DebugFlag = TRUE;
  375.  
  376.                     /* Look for a `Language' tooltype. */
  377.  
  378.                 if(Type = FindToolType(Icon -> do_ToolTypes,"LANGUAGE"))
  379.                     strcpy(Language,Type);
  380.  
  381.                     /* Look for a `Settings' tooltype. */
  382.  
  383.                 if(ConfigPath = FindToolType(Icon -> do_ToolTypes,"SETTINGS"))
  384.                 {
  385.                         /* Remember the path and continue. */
  386.  
  387.                     strcpy(ThePath,ConfigPath);
  388.  
  389.                     ConfigPath = ThePath;
  390.                 }
  391.  
  392.                     // Look for a `Phonebook' tooltype.
  393.  
  394.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PHONEBOOK"))
  395.                     strcpy(LastPhone,Type);
  396.  
  397.                 if(FindToolType(Icon -> do_ToolTypes,"AUTODIAL"))
  398.                     AutoDial = TRUE;
  399.  
  400.                 if(FindToolType(Icon -> do_ToolTypes,"AUTOEXIT"))
  401.                     AutoExit = TRUE;
  402.  
  403.                     /* Look for a `Portname' tooltype. */
  404.  
  405.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PORTNAME"))
  406.                     strcpy(RexxPortName,Type);
  407.                 else
  408.                     RexxPortName[0] = 0;
  409.  
  410.                     /* Look for a `Window' tooltype. */
  411.  
  412.                 if(Type = FindToolType(Icon -> do_ToolTypes,"WINDOW"))
  413.                     strcpy(WindowName,Type);
  414.                 else
  415.                     WindowName[0] = 0;
  416.  
  417.                     /* Look for a `Pubscreen' tooltype. */
  418.  
  419.                 if(Type = FindToolType(Icon -> do_ToolTypes,"PUBSCREEN"))
  420.                     strcpy(SomePubScreenName,Type);
  421.                 else
  422.                     SomePubScreenName[0] = 0;
  423.  
  424.                     /* Look for a `Startup' tooltype. */
  425.  
  426.                 if(Type = FindToolType(Icon -> do_ToolTypes,"STARTUP"))
  427.                     strcpy(StartupFile,Type);
  428.                 else
  429.                     StartupFile[0] = 0;
  430.  
  431.                     /* Look for a `Device' tooltype. */
  432.  
  433.                 if(Type = FindToolType(Icon -> do_ToolTypes,"DEVICE"))
  434.                 {
  435.                     if(Type[0])
  436.                     {
  437.                         strcpy(NewDevice,Type);
  438.  
  439.                         UseNewDevice = TRUE;
  440.                     }
  441.                 }
  442.  
  443.                     /* Look for a `Unit' tooltype. */
  444.  
  445.                 if(Type = FindToolType(Icon -> do_ToolTypes,"UNIT"))
  446.                 {
  447.                     if(Type[0])
  448.                     {
  449.                         NewUnit = Atol(Type);
  450.  
  451.                         UseNewUnit = TRUE;
  452.                     }
  453.                 }
  454.  
  455.                     /* Look for a `Quiet' tooltype. */
  456.  
  457.                 if(FindToolType(Icon -> do_ToolTypes,"QUIET"))
  458.                 {
  459.                     if(!StartupFile[0])
  460.                         DoIconify = TRUE;
  461.                 }
  462.  
  463.                     /* Look for a `Behind' tooltype. */
  464.  
  465.                 if(FindToolType(Icon -> do_ToolTypes,"BEHIND"))
  466.                     KeepQuiet = TRUE;
  467.  
  468.                     /* Free the icon. */
  469.  
  470.                 FreeDiskObject(Icon);
  471.             }
  472.  
  473.             CloseLibrary(IconBase);
  474.  
  475.             IconBase = NULL;
  476.         }
  477.  
  478.             /* Initialize this, so OpenAll will work with
  479.              * correct data.
  480.              */
  481.  
  482.         TermPort = (struct TermPort *)FindPort("term Port");
  483.  
  484.             /* We were called from Workbench. */
  485.  
  486.         if(Result = OpenAll(ConfigPath))
  487.         {
  488.             if(IntuitionBase && Result[0])
  489.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  490.  
  491.             CloseAll(TRUE);
  492.         }
  493.         else
  494.         {
  495.             if(StackSize(NULL) < 16384)
  496.             {
  497.                 LONG Success;
  498.  
  499.                 StackCall(&Success,16384,0,(LONG (* __stdargs)())HandleInput);
  500.             }
  501.             else
  502.                 HandleInput();
  503.         }
  504.     }
  505.  
  506.     return(RETURN_OK);
  507. }
  508.  
  509.     /* CloseLibs():
  510.      *
  511.      *    Plain and simple: close two libraries and clean up.
  512.      */
  513.  
  514. STATIC VOID
  515. CloseLibs(VOID)
  516. {
  517.     if(UtilityBase)
  518.     {
  519.         CloseLibrary(UtilityBase);
  520.  
  521.         UtilityBase = NULL;
  522.     }
  523.  
  524.     if(WBenchMsg)
  525.         CurrentDir(WBenchLock);
  526.  
  527.     if(DOSBase)
  528.     {
  529.         CloseLibrary(DOSBase);
  530.  
  531.         DOSBase = NULL;
  532.     }
  533.  
  534.     if(WBenchMsg)
  535.     {
  536.         Forbid();
  537.  
  538.         ReplyMsg((struct Message *)WBenchMsg);
  539.     }
  540. }
  541.  
  542.     /* ProcessCleanup(register __d1 BPTR SegList):
  543.      *
  544.      *    Frees all resource the main process has allocated when
  545.      *    it exits.
  546.      */
  547.  
  548. STATIC VOID __saveds __asm
  549. ProcessCleanup(register __d1 BPTR SegList)
  550. {
  551.     CloseAll(FALSE);
  552.  
  553.     Forbid();
  554.  
  555.     UnLoadSeg(SegList);
  556.  
  557.     CloseLibrary(DOSBase);
  558.  
  559.     DOSBase = NULL;
  560. }
  561.  
  562.     /* SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function):
  563.      *
  564.      *    Create a new process from the current one.
  565.      */
  566.  
  567. STATIC struct Process * __regargs
  568. SegmentSplit(STRPTR Name,BYTE Pri,LONG StackSize,APTR Function)
  569. {
  570.     struct Process            *Child;
  571.     struct CommandLineInterface    *CLI;
  572.  
  573.     CLI = (struct CommandLineInterface *)BADDR(((struct Process *)SysBase -> ThisTask) -> pr_CLI);
  574.  
  575.     Forbid();
  576.  
  577.     Child = CreateNewProcTags(
  578.         NP_CommandName,    "term",
  579.         NP_Name,    Name,
  580.         NP_Priority,    Pri,
  581.         NP_StackSize,    StackSize,
  582.         NP_Entry,    Function,
  583.         NP_Cli,        TRUE,
  584.         NP_ExitCode,    ProcessCleanup,
  585.         NP_ExitData,    CLI -> cli_Module,
  586.     TAG_DONE);
  587.  
  588.     if(Child)
  589.         CLI -> cli_Module = NULL;
  590.  
  591.     Permit();
  592.  
  593.     return(Child);
  594. }
  595.  
  596.     /* HandleInput():
  597.      *
  598.      *    This is our main input loop (check window & serial).
  599.      */
  600.  
  601. VOID __saveds
  602. HandleInput()
  603. {
  604.     BOOLEAN    AlmostFinished = FALSE;
  605.     BYTE    (* LocalSendLine)(register STRPTR,register LONG);
  606.  
  607.     ThisProcess = (struct Process *)SysBase -> ThisTask;
  608.  
  609.         /* Open the resources we need. */
  610.  
  611.     if(!IntuitionBase)
  612.     {
  613.         STRPTR Result;
  614.  
  615.         if(Result = OpenAll(ConfigPath))
  616.         {
  617.             if(IntuitionBase && Result[0])
  618.                 MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Result);
  619.  
  620.             if(WBenchMsg)
  621.                 CloseAll(TRUE);
  622.  
  623.             return;
  624.         }
  625.     }
  626.  
  627.         /* Tell the user what he probably doesn't know yet. */
  628.  
  629.     if(TermVersion > Config -> SerialConfig -> LastVersionSaved || (TermVersion == Config -> SerialConfig -> LastVersionSaved && TermRevision > Config -> SerialConfig -> LastRevisionSaved))
  630.     {
  631.         BlockWindows();
  632.  
  633.         ScreenToFront(Window -> WScreen);
  634.  
  635.         DisplayBeep(Window -> WScreen);
  636.         DisplayBeep(Window -> WScreen);
  637.  
  638.         ShowInfo(Window,LocaleString(MSG_ATTENTION_PLEASE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_REMINDER_TXT));
  639.  
  640.         ReleaseWindows();
  641.     }
  642.  
  643.         /* Give a hint. */
  644.  
  645.     if(Config -> MiscConfig -> ProtectiveMode && !FirstInvocation)
  646.     {
  647.         BlockWindows();
  648.  
  649.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> SerialConfig -> HandshakingProtocol == HANDSHAKING_NONE && !Config -> SerialConfig -> DirectConnection)
  650.         {
  651.             ScreenToFront(Window -> WScreen);
  652.  
  653.             if(MyEasyRequest(Window,LocaleString(MSG_NO_RTSCTS_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Config -> SerialConfig -> BaudRate))
  654.             {
  655.                 SaveConfig(Config,PrivateConfig);
  656.  
  657.                 Config -> SerialConfig -> HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
  658.  
  659.                 ConfigSetup();
  660.             }
  661.         }
  662.  
  663.         if(Config -> SerialConfig -> BaudRate >= 4800 && Config -> ModemConfig -> ConnectAutoBaud)
  664.         {
  665.             ScreenToFront(Window -> WScreen);
  666.  
  667.             if(MyEasyRequest(Window,LocaleString(MSG_AUTOBAUD_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  668.             {
  669.                 SaveConfig(Config,PrivateConfig);
  670.  
  671.                 Config -> ModemConfig -> ConnectAutoBaud = FALSE;
  672.  
  673.                 ConfigSetup();
  674.             }
  675.         }
  676.  
  677.         ReleaseWindows();
  678.     }
  679.  
  680.         // Don't confuse the user yet, do it later ;-)
  681.  
  682.     FirstInvocation = FALSE;
  683.  
  684.         /* Start the online timer if a carrier is present? */
  685.  
  686.     if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  687.     {
  688.             /* Is the carrier signal present? */
  689.  
  690.         if(!(GetSerialStatus() & CIAF_COMCD))
  691.         {
  692.                 /* Go into online state. */
  693.  
  694.             ObtainSemaphore(&OnlineSemaphore);
  695.  
  696.             WasOnline        = FALSE;
  697.             Online            = TRUE;
  698.  
  699.             ReleaseSemaphore(&OnlineSemaphore);
  700.  
  701.             BaudCount        = 0;
  702.             BaudBuffer[0]        = 0;
  703.             BaudPending        = FALSE;
  704.  
  705.             CurrentPay        = 0;
  706.  
  707.             ObtainSemaphore(&PatternSemaphore);
  708.  
  709.             ChosenEntry        = NULL;
  710.             ChosenPattern        = NULL;
  711.  
  712.             ReleaseSemaphore(&PatternSemaphore);
  713.  
  714.             Password[0]        = 0;
  715.             UserName[0]        = 0;
  716.  
  717.             SendStartup        = FALSE;
  718.  
  719.             LimitCount        = -1;
  720.  
  721.             CurrentBBSName[0]    = 0;
  722.             CurrentBBSComment[0]    = 0;
  723.             CurrentBBSNumber[0]    = 0;
  724.  
  725.             SetDialMenu(FALSE);
  726.         }
  727.     }
  728.  
  729.         /* Start up iconified? */
  730.  
  731.     if(DoIconify)
  732.     {
  733.         HandleIconify();
  734.  
  735.         DoIconify = FALSE;
  736.  
  737.         if(MainTerminated)
  738.             goto Stop;
  739.     }
  740.  
  741.     if(!KeepQuiet)
  742.         BumpWindow(Window);
  743.  
  744.         /* Set up the public screen data. */
  745.  
  746.     PubScreenStuff();
  747.  
  748.         /* Change program priority. */
  749.  
  750.     SetTaskPri(ThisProcess,(LONG)Config -> MiscConfig -> Priority);
  751.  
  752.     BlockWindows();
  753.  
  754.         /* Load the phone book. */
  755.  
  756.     LoadPhonebook(LastPhone,NULL);
  757.  
  758.         /* Build new menu strip. */
  759.  
  760.     if(!AttachMenu(NULL))
  761.     {
  762.         if(IntuitionBase)
  763.             MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMINIT_FAILED_TO_CREATE_MENUS_TXT));
  764.  
  765.         CloseAll(TRUE);
  766.  
  767.         return;
  768.     }
  769.     else
  770.     {
  771.         if(Online)
  772.             SetDialMenu(FALSE);
  773.     }
  774.  
  775.         /* Show our business card. */
  776.  
  777.     if(!StartupFile[0] && !Config -> CommandConfig -> StartupMacro[0] && !KeepQuiet && !(PhonebookAutoDial || AutoDial))
  778.     {
  779.         if(ShowAbout(TRUE))
  780.             while(HandleRexx());
  781.     }
  782.  
  783.     ReleaseWindows();
  784.  
  785.         /* Don't do anything silly. */
  786.  
  787.     KeepQuiet = FALSE;
  788.  
  789.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_STARTED_TXT),TermName,TermDate);
  790.  
  791.         /* Initialize the modem. */
  792.  
  793.     LocalSendLine    = SendLine;
  794.     SendLine    = SendLineDial;
  795.  
  796.     SerialCommand(Config -> ModemConfig -> ModemInit);
  797.  
  798.         /* Execute the startup macro (if any). */
  799.  
  800.     if(Config -> CommandConfig -> StartupMacro[0])
  801.         SerialCommand(Config -> CommandConfig -> StartupMacro);
  802.  
  803.     if(SendLine == SendLineDial)
  804.         SendLine = LocalSendLine;
  805.  
  806. #ifdef BETA
  807.     {
  808.         STRPTR Warning =
  809.             "\f  Just to make sure you know what you are using:\r\n"
  810.             "\r\n"
  811.             "     \033#6This really is a\r\n"
  812.             "        \033[5m\033#3BETA TEST\r\n"
  813.             "        \033#4BETA TEST\033[0m\r\n"
  814.             "         \033#6release!\r\n"
  815.             "\033#5\r\n"
  816.             "                   \033[4mDISCLAIMER:\033[0m\r\n"
  817.             "\r\n"
  818.             "This  product  is  meant  for educational purposes\r\n"
  819.             "only.   If   condition   persists,   consult  your\r\n"
  820.             "physician.  Edited  for  television. See label for\r\n"
  821.             "sequence.  Avoid  contact  with  skin. No purchase\r\n"
  822.             "necessary.  Use  only in well-ventilated area. Not\r\n"
  823.             "recommended  for  children.  No  anchovies  unless\r\n"
  824.             "otherwise  specified.  Driver does not carry cash.\r\n"
  825.             "This supersedes all previous notices.\r\n";
  826.  
  827.         ConProcess(Warning,strlen(Warning));
  828.     }
  829. #endif    // BETA
  830.  
  831.         // Check if we should dial some entries from the phonebook
  832.         // right upon startup
  833.  
  834.     if(PhonebookAutoDial || AutoDial)
  835.     {
  836.         LONG i,Count = 0;
  837.  
  838.         for(i = 0 ; i < NumPhoneEntries ; i++)
  839.         {
  840.             if(Phonebook[i] -> Header -> AutoDial && Phonebook[i] -> Header -> Number[0])
  841.             {
  842.                 Phonebook[i] -> Count = Count;
  843.  
  844.                 if(SortToList(NULL,Phonebook[i]))
  845.                     Count++;
  846.                 else
  847.                     Phonebook[i] -> Count = -1;
  848.             }
  849.         }
  850.  
  851.         if(Count > 0)
  852.         {
  853.             DoDial = DIAL_LIST;
  854.  
  855.             if(PhonebookAutoExit || AutoExit)
  856.                 KeepRedialing = TRUE;
  857.         }
  858.     }
  859.  
  860.         /* Go into input loop... */
  861.  
  862. Loop:    while(!MainTerminated)
  863.     {
  864.         if(Recording)
  865.         {
  866.             if(RecordingLine)
  867.                 Status = STATUS_RECORDING_LINE;
  868.             else
  869.                 Status = STATUS_RECORDING;
  870.         }
  871.  
  872.             /* Handle the signal responses. */
  873.  
  874.         if(DoDial != DIAL_LIST)
  875.             HandleResponse();
  876.  
  877.             // Rebuild the main menu?
  878.  
  879.         if(RebuildMenu)
  880.         {
  881.             struct Menu *Menu;
  882.  
  883.             if(Menu = BuildMenu())
  884.                 AttachMenu(Menu);
  885.             else
  886.                 DisconnectDialMenu();
  887.  
  888.             RebuildMenu = FALSE;
  889.         }
  890.  
  891.             /* Are we to run an ARexx script file? */
  892.  
  893.         if(StartupFile[0])
  894.         {
  895.             BlockWindows();
  896.  
  897.             SendARexxCommand(StartupFile,TRUE);
  898.  
  899.             ReleaseWindows();
  900.  
  901.             StartupFile[0] = 0;
  902.         }
  903.  
  904.             /* Are we to leave the main loop? */
  905.  
  906.         if(MainTerminated)
  907.             break;
  908.  
  909.             /* Make the user notice not too obvious events. */
  910.  
  911.         if(FlowInfo . Changed)
  912.             HandleFlowChange();
  913.  
  914.             /* Are we no longer online? */
  915.  
  916.         ObtainSemaphore(&OnlineSemaphore);
  917.  
  918.         if(!Online)
  919.         {
  920.             if(WasOnline)
  921.             {
  922.                 ReleaseSemaphore(&OnlineSemaphore);
  923.  
  924.                 HandleOnlineCleanup(HungUp);
  925.  
  926.                 ObtainSemaphore(&OnlineSemaphore);
  927.  
  928.                 WasOnline = FALSE;
  929.  
  930.                 ReleaseSemaphore(&OnlineSemaphore);
  931.  
  932.                 HungUp = FALSE;
  933.             }
  934.             else
  935.                 ReleaseSemaphore(&OnlineSemaphore);
  936.         }
  937.         else
  938.             ReleaseSemaphore(&OnlineSemaphore);
  939.  
  940.             /* Now for public screen mode changes. */
  941.  
  942.         if(FixPubScreenMode)
  943.             PubScreenStuff();
  944.  
  945.             /* Now for window size changes. */
  946.  
  947.         if(FixScreenSize)
  948.             ScreenSizeStuff();
  949.  
  950.             /* Somebody told us to re-open the display
  951.              * (changed the terminal emulation/colour
  952.              * mode, etc.).
  953.              */
  954.  
  955.         if(ResetDisplay)
  956.         {
  957.             if(!DisplayReset())
  958.                 break;
  959.         }
  960.  
  961.             /* Let's see if we still have to display the
  962.              * online cost.
  963.              */
  964.  
  965.         ObtainSemaphore(&OnlineSemaphore);
  966.  
  967.         if(CurrentPay && !Online)
  968.         {
  969.             ReleaseSemaphore(&OnlineSemaphore);
  970.  
  971.                 /* Reset the text rendering styles, font, etc. in
  972.                  * order to keep the following text from getting
  973.                  * illegible.
  974.                  */
  975.  
  976.             SoftReset();
  977.  
  978.                 /* Display how much we expect
  979.                  * the user will have to pay for
  980.                  * this call.
  981.                  */
  982.  
  983.             ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  984.  
  985.             CurrentPay = 0;
  986.         }
  987.         else
  988.             ReleaseSemaphore(&OnlineSemaphore);
  989.  
  990.             /* Iconify the program? */
  991.  
  992.         if(DoIconify)
  993.         {
  994.             HandleIconify();
  995.  
  996.             if(MainTerminated)
  997.                 break;
  998.         }
  999.  
  1000.             /* Reset the serial driver? */
  1001.  
  1002.         if(ResetSerial)
  1003.         {
  1004.             HandleSerialReset();
  1005.  
  1006.             if(MainTerminated)
  1007.                 break;
  1008.         }
  1009.  
  1010.             /* We are to release the serial.device (or
  1011.              * whatever we are using) for some reason.
  1012.              */
  1013.  
  1014.         if(ReleaseSerial)
  1015.         {
  1016.             HandleSerialRelease();
  1017.  
  1018.             if(MainTerminated)
  1019.                 break;
  1020.         }
  1021.  
  1022.             /* Invoke the dialing function? */
  1023.  
  1024.         if(DoDial != DIAL_IGNORE)
  1025.         {
  1026.             ObtainSemaphore(&OnlineSemaphore);
  1027.  
  1028.             if(Online)
  1029.             {
  1030.                 ReleaseSemaphore(&OnlineSemaphore);
  1031.  
  1032.                 FreeDialList(FALSE);
  1033.  
  1034.                 DoDial = DIAL_IGNORE;
  1035.  
  1036.                 Forbid();
  1037.  
  1038.                 if(DialMsg)
  1039.                 {
  1040.                     DialMsg -> rm_Result1 = RC_WARN;
  1041.                     DialMsg -> rm_Result2 = 0;
  1042.  
  1043.                     ReplyMsg(DialMsg);
  1044.  
  1045.                     DialMsg = NULL;
  1046.                 }
  1047.  
  1048.                 Permit();
  1049.             }
  1050.             else
  1051.             {
  1052.                 ReleaseSemaphore(&OnlineSemaphore);
  1053.  
  1054.                 if(DoDial == DIAL_LIST)
  1055.                 {
  1056.                     BYTE OldStatus = Status;
  1057.  
  1058.                     DoDial = DIAL_IGNORE;
  1059.  
  1060.                     BlockWindows();
  1061.  
  1062.                     DialPanel();
  1063.  
  1064.                     FreeDialList(FALSE);
  1065.  
  1066.                     Status = OldStatus;
  1067.  
  1068.                     SetRedialMenu();
  1069.  
  1070.                     ReleaseWindows();
  1071.                 }
  1072.                 else
  1073.                 {
  1074.                     DoDial = DIAL_IGNORE;
  1075.  
  1076.                     HandleMenuCode(MEN_REDIAL,NULL);
  1077.                 }
  1078.             }
  1079.         }
  1080.  
  1081.             /* Can we quit now? */
  1082.  
  1083.         if(AlmostFinished && !CantQuit)
  1084.             break;
  1085.     }
  1086.  
  1087.         /* Don't exit until all background processes
  1088.          * have terminated.
  1089.          */
  1090.  
  1091.     if(MainTerminated && CantQuit)
  1092.     {
  1093.         MainTerminated = FALSE;
  1094.         AlmostFinished = TRUE;
  1095.  
  1096.         goto Loop;
  1097.     }
  1098.  
  1099.         /* User wants to quit term, so let's try to close
  1100.          * our magnificient screen and exit.
  1101.          */
  1102.  
  1103. Stop:    if(Screen || SharedScreen)
  1104.     {
  1105.         struct Screen *WhichScreen;
  1106.  
  1107.             /* There can be only one... */
  1108.  
  1109.         if(Screen)
  1110.             WhichScreen = Screen;
  1111.         else
  1112.             WhichScreen = SharedScreen;
  1113.  
  1114.             // Can we quit now?
  1115.  
  1116.         if(!(PubScreenStatus(WhichScreen,PSNF_PRIVATE) & PSNF_PRIVATE))
  1117.         {
  1118.             BlockWindows();
  1119.  
  1120.             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  1121.  
  1122.             ReleaseWindows();
  1123.  
  1124.             AlmostFinished = MainTerminated = FALSE;
  1125.  
  1126.             goto Loop;
  1127.         }
  1128.     }
  1129.  
  1130.         /* Send the modem exit command, shut down the
  1131.          * serial.device and close all resources.
  1132.          */
  1133.  
  1134.     LocalSendLine    = SendLine;
  1135.     SendLine    = SendLineDial;
  1136.  
  1137.     SerialCommand(Config -> ModemConfig -> ModemExit);
  1138.  
  1139.     if(SendLine == SendLineDial)
  1140.         SendLine = LocalSendLine;
  1141.  
  1142.     ClearSerial();
  1143.  
  1144.     LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_PROGRAM_TERMINATED_TXT));
  1145.  
  1146.     Say(LocaleString(MSG_TERMMAIN_BYE_BYE_TXT));
  1147.  
  1148.     if(Phonebook && PhoneSize)
  1149.         DeletePhonebook(Phonebook,PhoneSize,TRUE);
  1150.  
  1151.         /* Clean up. */
  1152.  
  1153.     if(LocalCLI)
  1154.     {
  1155.         ThisProcess -> pr_CLI = OldCLI;
  1156.  
  1157.         DeleteCLI(LocalCLI);
  1158.     }
  1159.  
  1160.     if(!ThisProcess -> pr_CLI)
  1161.         CloseAll(TRUE);
  1162. }
  1163.  
  1164.     /* SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF):
  1165.      *
  1166.      *    Transmit text the user typed or pasted via the
  1167.      *    clipboard.
  1168.      */
  1169.  
  1170. STATIC VOID __regargs
  1171. SendInputTextBuffer(STRPTR Buffer,LONG Len,BOOL Bell,BOOL ConvertLF)
  1172. {
  1173.     UBYTE Mask,c;
  1174.  
  1175.     if(Config -> SerialConfig -> StripBit8)
  1176.         Mask = 0x7F;
  1177.     else
  1178.         Mask = 0xFF;
  1179.  
  1180.     while(Len--)
  1181.     {
  1182.         switch(CharType[c = (*Buffer++) & Mask])
  1183.         {
  1184.             case CHAR_ENTER:
  1185.  
  1186.                 if(Status == STATUS_HOLDING)
  1187.                 {
  1188.                     if(Bell)
  1189.                         BellSignal();
  1190.                 }
  1191.                 else
  1192.                 {
  1193.                     if(ConvertLF)
  1194.                     {
  1195.                         switch(Config -> TerminalConfig -> SendCR)
  1196.                         {
  1197.                             case EOL_LF:
  1198.  
  1199.                                 SerWrite("\n",1);
  1200.                                 break;
  1201.  
  1202.                             case EOL_CR:
  1203.  
  1204.                                 SerWrite("\r",1);
  1205.                                 break;
  1206.  
  1207.                             case EOL_LFCR:
  1208.  
  1209.                                 SerWrite("\n\r",2);
  1210.                                 break;
  1211.  
  1212.                             case EOL_CRLF:
  1213.  
  1214.                                 SerWrite("\r\n",2);
  1215.                                 break;
  1216.                         }
  1217.                     }
  1218.                     else
  1219.                     {
  1220.                         switch(Config -> TerminalConfig -> SendLF)
  1221.                         {
  1222.                             case EOL_LF:
  1223.  
  1224.                                 SerWrite("\n",1);
  1225.                                 break;
  1226.  
  1227.                             case EOL_CR:
  1228.  
  1229.                                 SerWrite("\r",1);
  1230.                                 break;
  1231.  
  1232.                             case EOL_LFCR:
  1233.  
  1234.                                 SerWrite("\n\r",2);
  1235.                                 break;
  1236.  
  1237.                             case EOL_CRLF:
  1238.  
  1239.                                 SerWrite("\r\n",2);
  1240.                                 break;
  1241.                         }
  1242.                     }
  1243.                 }
  1244.  
  1245.                 break;
  1246.  
  1247.             case CHAR_RETURN:
  1248.  
  1249.                 if(Status == STATUS_HOLDING)
  1250.                 {
  1251.                     if(Bell)
  1252.                         BellSignal();
  1253.                 }
  1254.                 else
  1255.                 {
  1256.                     switch(Config -> TerminalConfig -> SendCR)
  1257.                     {
  1258.                         case EOL_LF:
  1259.  
  1260.                             SerWrite("\n",1);
  1261.                             break;
  1262.  
  1263.                         case EOL_CR:
  1264.  
  1265.                             SerWrite("\r",1);
  1266.                             break;
  1267.  
  1268.                         case EOL_LFCR:
  1269.  
  1270.                             SerWrite("\n\r",2);
  1271.                             break;
  1272.  
  1273.                         case EOL_CRLF:
  1274.  
  1275.                             SerWrite("\r\n",2);
  1276.                             break;
  1277.                     }
  1278.                 }
  1279.  
  1280.                 break;
  1281.  
  1282.                 /* Stop in/output. */
  1283.  
  1284.             case CHAR_XON:
  1285.  
  1286.                 if(Config -> SerialConfig -> xONxOFF)
  1287.                     Status = STATUS_HOLDING;
  1288.  
  1289.                 if(Config -> SerialConfig -> PassThrough)
  1290.                     SerWrite(&c,1);
  1291.  
  1292.                 break;
  1293.  
  1294.                 /* Restart in/output. */
  1295.  
  1296.             case CHAR_XOFF:
  1297.  
  1298.                 if(Status == STATUS_HOLDING)
  1299.                     Status = STATUS_READY;
  1300.  
  1301.                 if(Config -> SerialConfig -> PassThrough)
  1302.                     SerWrite(&c,1);
  1303.  
  1304.                 break;
  1305.  
  1306.                 /* Any other character. */
  1307.  
  1308.             case CHAR_VANILLA:
  1309.  
  1310.                 if(Status == STATUS_HOLDING)
  1311.                 {
  1312.                     if(Bell)
  1313.                         BellSignal();
  1314.                 }
  1315.                 else
  1316.                 {
  1317.                     if(Config -> TerminalConfig -> FontMode == FONT_IBM)
  1318.                     {
  1319.                             /* Convert special
  1320.                              * Amiga characters into
  1321.                              * alien IBM dialect.
  1322.                              */
  1323.  
  1324.                         if(IBMConversion[c])
  1325.                             SerWrite(&IBMConversion[c],1);
  1326.                         else
  1327.                             SerWrite(&c,1);
  1328.                     }
  1329.                     else
  1330.                         SerWrite(&c,1);
  1331.                 }
  1332.  
  1333.                 break;
  1334.         }
  1335.     }
  1336. }
  1337.  
  1338.     /* HandleWindow():
  1339.      *
  1340.      *    This funny part checks the window(s) for incoming
  1341.      *    user input. Menus are handled elsewhere.
  1342.      */
  1343.  
  1344. BYTE
  1345. HandleWindow()
  1346. {
  1347.     STATIC ULONG         LastSeconds,LastMicros;
  1348.  
  1349.     struct IntuiMessage    *Message;
  1350.     ULONG             IClass,Code,Qualifier,Seconds,Micros;
  1351.     LONG             MouseX,MouseY,Len,GadgetID;
  1352.     struct Gadget        *Gadget;
  1353.     UBYTE             Char,InputBuffer[257];
  1354.     struct Window        *IDCMPWindow;
  1355.     BOOLEAN             Result = FALSE,ClickAndActivate = FALSE;
  1356.  
  1357.         /* Are we reading input from the clipboard? */
  1358.  
  1359.     if(ClipInput)
  1360.     {
  1361.         WORD Len = GetClip(InputBuffer,256,TRUE);
  1362.  
  1363.         if(Len < 0)
  1364.         {
  1365.             CloseClip();
  1366.  
  1367.             ClipInput = FALSE;
  1368.  
  1369.             if(ClipXerox)
  1370.             {
  1371.                 if(Config -> ClipConfig -> InsertSuffix[0])
  1372.                     SerialCommand(Config -> ClipConfig -> InsertSuffix);
  1373.  
  1374.                 ClipXerox = FALSE;
  1375.             }
  1376.  
  1377.             ClipPrefix = FALSE;
  1378.         }
  1379.         else
  1380.         {
  1381.             if(!ClipPrefix && ClipXerox)
  1382.             {
  1383.                 if(Config -> ClipConfig -> InsertPrefix[0])
  1384.                     SerialCommand(Config -> ClipConfig -> InsertPrefix);
  1385.  
  1386.                 ClipPrefix = TRUE;
  1387.             }
  1388.  
  1389.             if(Len > 0)
  1390.                 SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  1391.  
  1392.             Result = TRUE;
  1393.         }
  1394.     }
  1395.  
  1396.         /* Any news in the mail? */
  1397.  
  1398.     if(Message = (struct IntuiMessage *)GetMsg(Window -> UserPort))
  1399.     {
  1400.             /* A click into the window should activate it, but
  1401.              * we don't want to have the character snapping activated
  1402.              * under these conditions. In this case we rely upon
  1403.              * Intuition sending the IDCMP_ACTIVEWINDOW and
  1404.              * IDCMP_MOUSEBUTTONS event marked with the same
  1405.              * creation time stamp. Even if the Intuition
  1406.              * implementation should change no harm should
  1407.              * be done.
  1408.              */
  1409.  
  1410.         Seconds    = Message -> Seconds;
  1411.         Micros    = Message -> Micros;
  1412.  
  1413.         if(Seconds == LastSeconds && Micros == LastMicros && Message -> IDCMPWindow == Window)
  1414.         {
  1415.             if(Message -> Class == IDCMP_ACTIVEWINDOW || Message -> Class == IDCMP_MOUSEBUTTONS)
  1416.                 ClickAndActivate = TRUE;
  1417.         }
  1418.  
  1419.         LastSeconds    = Seconds;
  1420.         LastMicros    = Micros;
  1421.  
  1422.             /* Pick up the pieces. */
  1423.  
  1424.         IClass        = Message -> Class;
  1425.         Code        = Message -> Code;
  1426.         Qualifier    = Message -> Qualifier;
  1427.         Gadget        = (struct Gadget *)Message -> IAddress;
  1428.  
  1429.         MouseX        = Message -> MouseX;
  1430.         MouseY        = Message -> MouseY;
  1431.  
  1432.         IDCMPWindow    = Message -> IDCMPWindow;
  1433.  
  1434.         if(IClass == IDCMP_IDCMPUPDATE)
  1435.             GadgetID = GetTagData(GA_ID,0,(struct TagItem *)Gadget);
  1436.  
  1437.         if(IClass == IDCMP_RAWKEY)
  1438.         {
  1439.                 /* Perform key conversion. */
  1440.  
  1441.             if(XEmulatorBase)
  1442.             {
  1443.                 if(Len = XEmulatorUserMon(XEM_IO,InputBuffer,256,Message))
  1444.                     Char = InputBuffer[0];
  1445.             }
  1446.             else
  1447.                 Char = KeyConvert(Message,InputBuffer,&Len);
  1448.         }
  1449.  
  1450.         ReplyMsg(Message);
  1451.     }
  1452.     else
  1453.         IClass = NULL;
  1454.  
  1455.         /* Did we get any information? */
  1456.  
  1457.     if(IClass)
  1458.     {
  1459.             /* The following messages probably
  1460.              * originated from the fast! macro
  1461.              * panel.
  1462.              */
  1463.  
  1464.         if(IDCMPWindow == FastWindow)
  1465.         {
  1466.             switch(IClass)
  1467.             {
  1468.                     /* Close the window. */
  1469.  
  1470.  
  1471.                 case IDCMP_CLOSEWINDOW:
  1472.  
  1473.                     CloseFastWindow();
  1474.  
  1475.                     return(TRUE);
  1476.  
  1477.                     /* Window size has changed for some reason. */
  1478.  
  1479.                 case IDCMP_NEWSIZE:
  1480.  
  1481.                     RefreshFastWindow(FALSE);
  1482.  
  1483.                     return(TRUE);
  1484.  
  1485.                     /* Some gadget was invoked. */
  1486.  
  1487.                 case IDCMP_GADGETUP:
  1488.                 case IDCMP_GADGETDOWN:
  1489.  
  1490.                     GadgetID = Gadget -> GadgetID;
  1491.  
  1492.                 case IDCMP_MOUSEMOVE:
  1493.                 case IDCMP_IDCMPUPDATE:
  1494.  
  1495.                     HandleFastWindowGadget(IClass,Code,GadgetID);
  1496.  
  1497.                     return(TRUE);
  1498.             }
  1499.         }
  1500.  
  1501.             /* Status window activated? */
  1502.  
  1503.         if(IDCMPWindow == StatusWindow)
  1504.         {
  1505.             if(IClass == IDCMP_ACTIVEWINDOW && !Config -> ScreenConfig -> SplitStatus)
  1506.                 NormalCursor();
  1507.  
  1508.             if(IClass == IDCMP_CLOSEWINDOW)
  1509.             {
  1510.                 Forbid();
  1511.  
  1512.                 ClrSignal(SIG_HANDSHAKE);
  1513.  
  1514.                 Signal(StatusProcess,SIG_CLOSEWINDOW);
  1515.  
  1516.                 Wait(SIG_HANDSHAKE);
  1517.  
  1518.                 Permit();
  1519.  
  1520.                 ClearMenuStrip(StatusWindow);
  1521.                 CloseWindowSafely(StatusWindow);
  1522.  
  1523.                 StatusWindow = NULL;
  1524.             }
  1525.         }
  1526.  
  1527.             // What about the matrix window?
  1528.  
  1529.         if(IDCMPWindow == MatrixWindow)
  1530.         {
  1531.             if(DispatchMatrixWindow(&IClass,Code,Qualifier,Char))
  1532.                 CloseMatrixWindow();
  1533.         }
  1534.  
  1535.             /* Main window message? */
  1536.  
  1537.         if(IDCMPWindow == Window)
  1538.         {
  1539.             switch(IClass)
  1540.             {
  1541.                 case IDCMP_INACTIVEWINDOW:
  1542.  
  1543.                     HoldClick = FALSE;
  1544.  
  1545.                     GhostCursor();
  1546.  
  1547.                     break;
  1548.  
  1549.                 case IDCMP_ACTIVEWINDOW:
  1550.  
  1551.                         // Take care of the chat gadget if necessary
  1552.  
  1553.                     ActivateChat(TRUE);
  1554.  
  1555.                     NormalCursor();
  1556.  
  1557.                     break;
  1558.  
  1559.                 case IDCMP_NEWSIZE:
  1560.  
  1561.                         /* Is a window clipping region installed? */
  1562.  
  1563.                     if(ClipRegion)
  1564.                     {
  1565.                         struct Rectangle RegionRectangle;
  1566.  
  1567.                             /* Install old region. */
  1568.  
  1569.                         InstallClipRegion(Window -> WLayer,OldRegion);
  1570.  
  1571.                             /* Fill in the clipping rectangle. */
  1572.  
  1573.                         RegionRectangle . MinX = Window -> BorderLeft;
  1574.                         RegionRectangle . MinY = Window -> BorderTop;
  1575.                         RegionRectangle . MaxX = Window -> Width - (Window -> BorderRight + 1);
  1576.                         RegionRectangle . MaxY = Window -> Height - (Window -> BorderBottom + 1);
  1577.  
  1578.                             /* Clear previous clipping region. */
  1579.  
  1580.                         ClearRegion(ClipRegion);
  1581.  
  1582.                             /* Set new clipping region. */
  1583.  
  1584.                         OrRectRegion(ClipRegion,&RegionRectangle);
  1585.  
  1586.                             /* Install new clipping region. */
  1587.  
  1588.                         OldRegion = InstallClipRegion(Window -> WLayer,ClipRegion);
  1589.                     }
  1590.  
  1591.                     ForceStatusUpdate();
  1592.  
  1593.                     HandleMenuCode(MEN_RESET_TERMINAL,Qualifier);
  1594.  
  1595.                         // Take care of the chat gadget if necessary
  1596.  
  1597.                     ActivateChat(TRUE);
  1598.  
  1599.                     TTYResize();
  1600.  
  1601.                     break;
  1602.  
  1603.                 case IDCMP_CLOSEWINDOW:
  1604.  
  1605.                     HandleMenuCode(MEN_QUIT,Qualifier);
  1606.                     break;
  1607.  
  1608.                 case IDCMP_MOUSEMOVE:
  1609.  
  1610.                     if(HoldClick)
  1611.                     {
  1612.                         if(!Marking)
  1613.                             SetMarker(ClickX,ClickY);
  1614.                         else
  1615.                         {
  1616.                             MouseX -= WindowLeft;
  1617.  
  1618.                             if(MouseX < 0)
  1619.                                 MouseX = 0;
  1620.  
  1621.                             if(MouseX > WindowWidth - 1)
  1622.                                 MouseX = WindowWidth - 1;
  1623.  
  1624.                             MouseY -= WindowTop;
  1625.  
  1626.                             if(MouseY < 0)
  1627.                                 MouseY = 0;
  1628.  
  1629.                             if(MouseY > WindowHeight - 1)
  1630.                                 MouseY = WindowHeight - 1;
  1631.  
  1632.                             MoveMarker(MouseX,MouseY);
  1633.                         }
  1634.                     }
  1635.  
  1636.                     break;
  1637.  
  1638.                 case IDCMP_MOUSEBUTTONS:
  1639.  
  1640.                     if(Code == SELECTUP)
  1641.                         ActivateChat(TRUE);
  1642.  
  1643.                     if((!ClickAndActivate || Code != SELECTDOWN) && (!XEmulatorBase || Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL))
  1644.                     {
  1645.                         if(Code == SELECTUP)
  1646.                             HoldClick = FALSE;
  1647.  
  1648.                         if(Code == SELECTDOWN)
  1649.                         {
  1650.                             MouseX -= WindowLeft;
  1651.  
  1652.                             if(MouseX < 0)
  1653.                                 MouseX = 0;
  1654.  
  1655.                             if(MouseX > WindowWidth - 1)
  1656.                                 MouseX = WindowWidth - 1;
  1657.  
  1658.                             MouseY -= WindowTop;
  1659.  
  1660.                             if(MouseY < 0)
  1661.                                 MouseY = 0;
  1662.  
  1663.                             if(MouseY > WindowHeight - 1)
  1664.                                 MouseY = WindowHeight - 1;
  1665.  
  1666.                             HoldClick = TRUE;
  1667.  
  1668.                             if(Qualifier & IEQUALIFIER_CONTROL)
  1669.                             {
  1670.                                 WORD FirstX,FirstY;
  1671.  
  1672.                                 FirstX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator);
  1673.                                 FirstY = MouseY / TextFontHeight;
  1674.  
  1675.                                 if(FirstX < RasterWidth && FirstY < RasterHeight)
  1676.                                 {
  1677.                                     UBYTE Char;
  1678.  
  1679.                                     ObtainSemaphore(RasterSemaphore);
  1680.  
  1681.                                     Char = Raster[FirstY * RasterWidth + FirstX];
  1682.  
  1683.                                     ReleaseSemaphore(RasterSemaphore);
  1684.  
  1685.                                     if(Char)
  1686.                                     {
  1687.                                         SerWrite(&Char,1);
  1688.  
  1689.                                         if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1690.                                         {
  1691.                                             switch(Config -> TerminalConfig -> SendCR)
  1692.                                             {
  1693.                                                 case EOL_LF:
  1694.  
  1695.                                                     SerWrite("\n",1);
  1696.                                                     break;
  1697.  
  1698.                                                 case EOL_CR:
  1699.  
  1700.                                                     SerWrite("\r",1);
  1701.                                                     break;
  1702.  
  1703.                                                 case EOL_LFCR:
  1704.  
  1705.                                                     SerWrite("\n\r",2);
  1706.                                                     break;
  1707.  
  1708.                                                 case EOL_CRLF:
  1709.  
  1710.                                                     SerWrite("\r\n",2);
  1711.                                                     break;
  1712.                                             }
  1713.                                         }
  1714.                                     }
  1715.                                 }
  1716.  
  1717.                                 return(TRUE);
  1718.                             }
  1719.  
  1720.                             if((Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT)) && (Qualifier & IEQUALIFIER_LEFTBUTTON))
  1721.                             {
  1722.                                 WORD DeltaX,DeltaY;
  1723.  
  1724.                                 ObtainSemaphore(&TerminalSemaphore);
  1725.  
  1726.                                 DeltaX = (MouseX * CharCellDenominator) / (TextFontWidth * CharCellNominator)  - CursorX;
  1727.                                 DeltaY = MouseY / TextFontHeight - CursorY;
  1728.  
  1729.                                 ReleaseSemaphore(&TerminalSemaphore);
  1730.  
  1731.                                 if(DeltaX || DeltaY)
  1732.                                 {
  1733.                                     if(DeltaX > 0)
  1734.                                     {
  1735.                                         DeltaX++;
  1736.  
  1737.                                         while(DeltaX--)
  1738.                                             SerWrite("\33[C",3);
  1739.                                     }
  1740.  
  1741.                                     if(DeltaX < 0)
  1742.                                     {
  1743.                                         while(DeltaX++)
  1744.                                             SerWrite("\33[D",3);
  1745.                                     }
  1746.  
  1747.                                     if(DeltaY > 0)
  1748.                                     {
  1749.                                         DeltaY++;
  1750.  
  1751.                                         while(DeltaY--)
  1752.                                             SerWrite("\33[B",3);
  1753.                                     }
  1754.  
  1755.                                     if(DeltaY < 0)
  1756.                                     {
  1757.                                         while(DeltaY++)
  1758.                                             SerWrite("\33[A",3);
  1759.                                     }
  1760.                                 }
  1761.  
  1762.                                 return(TRUE);
  1763.                             }
  1764.  
  1765.                             ReportMouse(TRUE,Window);
  1766.  
  1767.                             if(!FirstClick)
  1768.                             {
  1769.                                 ULONG CurrentSecs,CurrentMicros;
  1770.  
  1771.                                 CurrentTime(&CurrentSecs,&CurrentMicros);
  1772.  
  1773.                                 FirstClick = TRUE;
  1774.  
  1775.                                 if(ABS(ClickX - MouseX) <= TextFontWidth && ABS(ClickY - MouseY) <= TextFontHeight && DoubleClick(ClickSecs,ClickMicros,CurrentSecs,CurrentMicros))
  1776.                                 {
  1777.                                     DropMarker();
  1778.  
  1779.                                     MarkWord(ClickX,ClickY);
  1780.  
  1781.                                     return(TRUE);
  1782.                                 }
  1783.                                 else
  1784.                                 {
  1785.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1786.  
  1787.                                     FirstClick    = FALSE;
  1788.  
  1789.                                     ClickX        = MouseX;
  1790.                                     ClickY        = MouseY;
  1791.                                 }
  1792.                             }
  1793.                             else
  1794.                             {
  1795.                                 CurrentTime(&ClickSecs,&ClickMicros);
  1796.  
  1797.                                 FirstClick    = FALSE;
  1798.  
  1799.                                 ClickX        = MouseX;
  1800.                                 ClickY        = MouseY;
  1801.                             }
  1802.  
  1803.                             if(Marking)
  1804.                             {
  1805.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1806.                                     MoveMarker(MouseX,MouseY);
  1807.                                 else
  1808.                                 {
  1809.                                     DropMarker();
  1810.  
  1811.                                     CurrentTime(&ClickSecs,&ClickMicros);
  1812.  
  1813.                                     FirstClick    = FALSE;
  1814.  
  1815.                                     ClickX        = MouseX;
  1816.                                     ClickY        = MouseY;
  1817.  
  1818.                                     ReportMouse(TRUE,Window);
  1819.                                 }
  1820.                             }
  1821.                         }
  1822.                     }
  1823.  
  1824.                     break;
  1825.             }
  1826.         }
  1827.  
  1828.             /* Now for general information. */
  1829.  
  1830.         switch(IClass)
  1831.         {
  1832.             case IDCMP_REFRESHWINDOW:
  1833.  
  1834.                 BeginRefresh(IDCMPWindow);
  1835.                 EndRefresh(IDCMPWindow,TRUE);
  1836.                 break;
  1837.  
  1838.             case IDCMP_RAWKEY:
  1839.  
  1840.                     /* Take care of the numeric keypad. */
  1841.  
  1842.                 if((Qualifier & IEQUALIFIER_NUMERICPAD) && (Config -> EmulationConfig -> NumericMode == KEYMODE_APPLICATION))
  1843.                 {
  1844.                     STATIC STRPTR StringTable[22][2] =
  1845.                     {
  1846.                         "0",    "\033Op",
  1847.                         "1",    "\033Oq",
  1848.                         "2",    "\033Or",
  1849.                         "3",    "\033Os",
  1850.                         "4",    "\033Ot",
  1851.                         "5",    "\033Ou",
  1852.                         "6",    "\033Ov",
  1853.                         "7",    "\033Ow",
  1854.                         "8",    "\033Ox",
  1855.                         "9",    "\033Oy",
  1856.                         "-",    "\033Om",
  1857.                         "+",    "\033Ol",    // This should really be a comma
  1858.                         ".",    "\033On",
  1859.  
  1860.                         "(",    "\033OP",
  1861.                         "[",    "\033OP",
  1862.                         "{",    "\033OP",
  1863.                         "]",    "\033OQ",
  1864.                         ")",    "\033OQ",
  1865.                         "}",    "\033OQ",
  1866.                         "/",    "\033OR",
  1867.                         "*",    "\033OS",
  1868.  
  1869.                         "\r",    "\033OM"
  1870.                     };
  1871.  
  1872.                     STATIC struct { UBYTE Code; STRPTR String; } CodeTable[18] =
  1873.                     {
  1874.                         0x0F,    "\033Op",    // "0"
  1875.                         0x1D,    "\033Oq",    // "1"
  1876.                         0x1E,    "\033Or",    // "2"
  1877.                         0x1F,    "\033Os",    // "3"
  1878.                         0x2D,    "\033Ot",    // "4"
  1879.                         0x2E,    "\033Ou",    // "5"
  1880.                         0x2F,    "\033Ov",    // "6"
  1881.                         0x3D,    "\033Ow",    // "7"
  1882.                         0x3E,    "\033Ox",    // "8"
  1883.                         0x3F,    "\033Oy",    // "9"
  1884.                         0x4A,    "\033Om",    // "-"
  1885.                         0x5E,    "\033Ol",    // "+", but this should really be a comma
  1886.                         0x3C,    "\033On",    // "."
  1887.  
  1888.                         0x5A,    "\033OP",    // "["
  1889.                         0x5B,    "\033OQ",    // "]"
  1890.                         0x5C,    "\033OR",    // "/"
  1891.                         0x5D,    "\033OS",    // "*"
  1892.  
  1893.                         0x43,    "\033OM"    // <cr>
  1894.                     };
  1895.  
  1896.                     STRPTR    String = NULL;
  1897.                     WORD    i;
  1898.  
  1899.                     for(i = 0 ; i < 22 ; i++)
  1900.                     {
  1901.                         if(Char == StringTable[i][0][0])
  1902.                         {
  1903.                             String = StringTable[i][1];
  1904.  
  1905.                             break;
  1906.                         }
  1907.                     }
  1908.  
  1909.                     if(!String)
  1910.                     {
  1911.                         for(i = 0 ; i < 18 ; i++)
  1912.                         {
  1913.                             if(Code == CodeTable[i] . Code)
  1914.                             {
  1915.                                 String = CodeTable[i] . String;
  1916.  
  1917.                                 break;
  1918.                             }
  1919.                         }
  1920.                     }
  1921.  
  1922.                     if(String)
  1923.                     {
  1924.                         if(ClipInput)
  1925.                         {
  1926.                             CloseClip();
  1927.  
  1928.                             ClipInput = ClipXerox = ClipPrefix = FALSE;
  1929.                         }
  1930.  
  1931.                         SerWrite(String,strlen(String));
  1932.  
  1933.                         Len = 0;
  1934.                     }
  1935.                 }
  1936.  
  1937.                     /* This looks like a raw, or better, now cooked key. */
  1938.  
  1939.                 if(Len)
  1940.                 {
  1941.                     switch(CharType[Char])
  1942.                     {
  1943.                         case CHAR_HELP:
  1944.  
  1945.                             GuideDisplay(CONTEXT_MAIN);
  1946.  
  1947.                             Len = 0;
  1948.  
  1949.                             break;
  1950.  
  1951.                         case CHAR_CURSOR:
  1952.  
  1953.                             if(ClipInput)
  1954.                             {
  1955.                                 CloseClip();
  1956.  
  1957.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  1958.                             }
  1959.  
  1960.                                 /* If in cursor key applications mode,
  1961.                                  * send the corresponding string.
  1962.                                  */
  1963.  
  1964.                             if(Config -> EmulationConfig -> CursorMode == KEYMODE_APPLICATION)
  1965.                             {
  1966.                                 STATIC STRPTR CursorTable[4] =
  1967.                                 {
  1968.                                     "\033OA",
  1969.                                     "\033OB",
  1970.                                     "\033OC",
  1971.                                     "\033OD"
  1972.                                 };
  1973.  
  1974.                                 SerWrite(CursorTable[Char - CUP],3);
  1975.                             }
  1976.                             else
  1977.                             {
  1978.                                 WORD QualType;
  1979.  
  1980.                                     /* Find the appropriate qualifier. */
  1981.  
  1982.                                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  1983.                                     QualType = 1;
  1984.                                 else
  1985.                                 {
  1986.                                     if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  1987.                                         QualType = 2;
  1988.                                     else
  1989.                                     {
  1990.                                         if(Qualifier & IEQUALIFIER_CONTROL)
  1991.                                             QualType = 3;
  1992.                                         else
  1993.                                             QualType = 0;
  1994.                                     }
  1995.                                 }
  1996.  
  1997.                                     /* Send the corresponding string. */
  1998.  
  1999.                                 SerialCommand(CursorKeys -> Keys[QualType][Char - CUP]);
  2000.                             }
  2001.  
  2002.                             Len = 0;
  2003.  
  2004.                             break;
  2005.  
  2006.                             /* Any function key pressed? */
  2007.  
  2008.                         case CHAR_FUNCTION:
  2009.  
  2010.                             if(ClipInput)
  2011.                             {
  2012.                                 CloseClip();
  2013.  
  2014.                                 ClipInput = ClipXerox = ClipPrefix = FALSE;
  2015.                             }
  2016.  
  2017.                             if(Qualifier & IEQUALIFIER_CONTROL)
  2018.                                 SerialCommand(MacroKeys -> Keys[3][Char - FN1]);
  2019.                             else
  2020.                             {
  2021.                                 if(Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  2022.                                     SerialCommand(MacroKeys -> Keys[2][Char - FN1]);
  2023.                                 else
  2024.                                 {
  2025.                                     if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2026.                                         SerialCommand(MacroKeys -> Keys[1][Char - FN1]);
  2027.                                     else
  2028.                                         SerialCommand(MacroKeys -> Keys[0][Char - FN1]);
  2029.                                 }
  2030.                             }
  2031.  
  2032.                             Len = 0;
  2033.  
  2034.                             break;
  2035.  
  2036.                             /* Anything else? */
  2037.  
  2038.                         default:
  2039.  
  2040.                             if(Len == 1 && Char == '\r' && Recording && !RecordingLine && (Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2041.                             {
  2042.                                 RememberInputText("\r",1);
  2043.  
  2044.                                 Len = 0;
  2045.  
  2046.                                 RecordingLine = TRUE;
  2047.  
  2048.                                 RememberResetInput();
  2049.  
  2050.                                 RememberOutput = FALSE;
  2051.                                 RememberInput = TRUE;
  2052.  
  2053.                                 CheckItem(MEN_RECORD_LINE,TRUE);
  2054.                             }
  2055.  
  2056.                             break;
  2057.                     }
  2058.  
  2059.                         /* Any characters to send? */
  2060.  
  2061.                     if(Len)
  2062.                         SendInputTextBuffer(InputBuffer,Len,TRUE,FALSE);
  2063.                 }
  2064.  
  2065.                 break;
  2066.  
  2067.                 /* A menu item was selected. */
  2068.  
  2069.             case IDCMP_MENUPICK:
  2070.  
  2071.                 HandleMenu(Code,Qualifier);
  2072.  
  2073.                     // Take care of the chat gadget if necessary
  2074.  
  2075.                 ActivateChat(TRUE);
  2076.  
  2077.                 break;
  2078.  
  2079.                 /* Menu help is required. */
  2080.  
  2081.             case IDCMP_MENUHELP:
  2082.  
  2083.                 if(MENUNUM(Code) == NOMENU || MENUNUM(Code) > 9 || ITEMNUM(Code) == NOITEM)
  2084.                     GuideDisplay(CONTEXT_MAIN_MENU);
  2085.                 else
  2086.                     GuideDisplay(CONTEXT_PROJECT_MEN + MENUNUM(Code));
  2087.  
  2088.                 break;
  2089.         }
  2090.  
  2091.         return(TRUE);
  2092.     }
  2093.  
  2094.     return(Result);
  2095. }
  2096.  
  2097.     /* HandleLocalDialList(BYTE ClearIt):
  2098.      *
  2099.      *    Invoke the local dialing list or clear it.
  2100.      */
  2101.  
  2102. STATIC VOID __regargs
  2103. HandleLocalDialList(BYTE ClearIt)
  2104. {
  2105.     if(Menu)
  2106.     {
  2107.         struct Menu    *ThisMenu;
  2108.         struct MenuItem    *Item;
  2109.  
  2110.         if(Window)
  2111.             ClearMenuStrip(Window);
  2112.  
  2113.         if(StatusWindow)
  2114.             ClearMenuStrip(StatusWindow);
  2115.  
  2116.         if(FastWindow)
  2117.             ClearMenuStrip(FastWindow);
  2118.  
  2119.         for(ThisMenu = Menu ; ThisMenu ; ThisMenu = ThisMenu -> NextMenu)
  2120.         {
  2121.             if(Item = ThisMenu -> FirstItem)
  2122.             {
  2123.                 do
  2124.                 {
  2125.                     if((ULONG)GTMENUITEM_USERDATA(Item) >= DIAL_MENU_LIMIT)
  2126.                         Item -> Flags &= ~CHECKED;
  2127.  
  2128.                     if(Item -> SubItem)
  2129.                     {
  2130.                         struct MenuItem *SubItem = Item -> SubItem;
  2131.  
  2132.                         do
  2133.                         {
  2134.                             if((ULONG)GTMENUITEM_USERDATA(SubItem) >= DIAL_MENU_LIMIT)
  2135.                                 SubItem -> Flags &= ~CHECKED;
  2136.                         }
  2137.                         while(SubItem = SubItem -> NextItem);
  2138.                     }
  2139.                 }
  2140.                 while(Item = Item -> NextItem);
  2141.             }
  2142.         }
  2143.  
  2144.         if(Window)
  2145.             ResetMenuStrip(Window,Menu);
  2146.  
  2147.         if(StatusWindow)
  2148.             ResetMenuStrip(StatusWindow,Menu);
  2149.  
  2150.         if(FastWindow)
  2151.             ResetMenuStrip(FastWindow,Menu);
  2152.     }
  2153.  
  2154.     if(LocalDialList)
  2155.     {
  2156.         ObtainSemaphore(&OnlineSemaphore);
  2157.  
  2158.         if(LocalDialList -> lh_Head -> ln_Succ && !Online && !ClearIt)
  2159.         {
  2160.             ReleaseSemaphore(&OnlineSemaphore);
  2161.  
  2162.             FreeDialList(TRUE);
  2163.  
  2164.             DialList = LocalDialList;
  2165.  
  2166.             LocalDialList = NULL;
  2167.  
  2168.             LocalCount = -1;
  2169.  
  2170.             SetRedialMenu();
  2171.  
  2172.             HandleMenuCode(MEN_REDIAL,NULL);
  2173.         }
  2174.         else
  2175.         {
  2176.             ReleaseSemaphore(&OnlineSemaphore);
  2177.  
  2178.             FreeList(LocalDialList);
  2179.  
  2180.             FreeVecPooled(LocalDialList);
  2181.  
  2182.             LocalDialList = NULL;
  2183.  
  2184.             LocalCount = -1;
  2185.         }
  2186.     }
  2187. }
  2188.  
  2189.     /* HandleMenuCode(ULONG Code,ULONG Qualifier):
  2190.      *
  2191.      *    Handle each function associated with a menu code.
  2192.      */
  2193.  
  2194. VOID __regargs
  2195. HandleMenuCode(ULONG Code,ULONG Qualifier)
  2196. {
  2197.     struct FileRequester    *FileRequest;
  2198.     UBYTE             DummyBuffer[MAX_FILENAME_LENGTH],
  2199.                 *DummyChar;
  2200.     BYTE             OldStatus = Status;
  2201.  
  2202.     BPTR             SomeFile;
  2203.     APTR             OldPtr;
  2204.  
  2205.     struct MenuItem        *Item;
  2206.  
  2207.     switch(Code)
  2208.     {
  2209.             /* Save screen as IFF-ILBM file. */
  2210.  
  2211.         case MEN_SAVE_AS_PICTURE:
  2212.  
  2213.             BlockWindows();
  2214.  
  2215.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_IFF_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),TRUE))
  2216.             {
  2217.                 if(!SaveWindow(DummyBuffer,Window))
  2218.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  2219.  
  2220.                 FreeAslRequest(FileRequest);
  2221.             }
  2222.  
  2223.             ReleaseWindows();
  2224.  
  2225.             break;
  2226.  
  2227.             /* Save screen as ASCII file. */
  2228.  
  2229.         case MEN_SAVE_AS_TEXT:
  2230.  
  2231.             BlockWindows();
  2232.  
  2233.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_SCREEN_ASCII_TXT),"","",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  2234.             {
  2235.                 LONG Error = 0;
  2236.  
  2237.                 if(GetFileSize(DummyBuffer))
  2238.                 {
  2239.                     switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  2240.                     {
  2241.                         case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2242.                             break;
  2243.  
  2244.                         case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  2245.                             {
  2246.                                 if(Seek(SomeFile,0,OFFSET_END) == -1)
  2247.                                 {
  2248.                                     Close(SomeFile);
  2249.  
  2250.                                     SomeFile = NULL;
  2251.                                 }
  2252.                             }
  2253.  
  2254.                             break;
  2255.  
  2256.                         case 0:    SomeFile = ~0;
  2257.                             break;
  2258.                     }
  2259.                 }
  2260.                 else
  2261.                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  2262.  
  2263.                 if(SomeFile)
  2264.                 {
  2265.                     if(SomeFile != ~0)
  2266.                     {
  2267.                         LONG     i,j;
  2268.                         UBYTE    *Buffer;
  2269.  
  2270.                         for(i = 0 ; i < RasterHeight ; i++)
  2271.                         {
  2272.                             Buffer = &Raster[i * RasterWidth];
  2273.  
  2274.                             j = RasterWidth - 1;
  2275.  
  2276.                             while(j >= 0 && Buffer[j] == ' ')
  2277.                                 j--;
  2278.  
  2279.                             if(j >= 0)
  2280.                             {
  2281.                                 SetIoErr(0);
  2282.  
  2283.                                 if(FWrite(SomeFile,Buffer,j + 1,1) < 1)
  2284.                                 {
  2285.                                     Error = IoErr();
  2286.  
  2287.                                     break;
  2288.                                 }
  2289.                             }
  2290.  
  2291.                             SetIoErr(0);
  2292.  
  2293.                             if(FWrite(SomeFile,"\n",1,1) < 1)
  2294.                             {
  2295.                                 Error = IoErr();
  2296.  
  2297.                                 break;
  2298.                             }
  2299.                         }
  2300.  
  2301.                         Close(SomeFile);
  2302.  
  2303.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  2304.  
  2305.                         if(Config -> MiscConfig -> CreateIcons)
  2306.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  2307.                     }
  2308.                 }
  2309.                 else
  2310.                     Error = IoErr();
  2311.  
  2312.                 if(Error)
  2313.                     ShowError(Window,ERR_SAVE_ERROR,Error,DummyBuffer);
  2314.  
  2315.                 FreeAslRequest(FileRequest);
  2316.             }
  2317.  
  2318.             ReleaseWindows();
  2319.  
  2320.             break;
  2321.  
  2322.             /* Print the screen (pure ASCII). */
  2323.  
  2324.         case MEN_PRINT_SCREEN:
  2325.  
  2326.             BlockWindows();
  2327.  
  2328.             if(RasterEnabled)
  2329.                 PrintSomething(PRINT_SCREEN);
  2330.             else
  2331.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_NO_DATA_TO_PRINT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  2332.  
  2333.             ReleaseWindows();
  2334.  
  2335.             break;
  2336.  
  2337.             /* Print the screen (graphics). */
  2338.  
  2339.         case MEN_PRINT_SCREEN_AS_GFX:
  2340.  
  2341.             BlockWindows();
  2342.  
  2343.             PrintScreenGfx();
  2344.  
  2345.             ReleaseWindows();
  2346.  
  2347.             break;
  2348.  
  2349.             /* Print the clipboard contents. */
  2350.  
  2351.         case MEN_PRINT_CLIP:
  2352.  
  2353.             BlockWindows();
  2354.  
  2355.             PrintSomething(PRINT_CLIP);
  2356.  
  2357.             ReleaseWindows();
  2358.  
  2359.             break;
  2360.  
  2361.             /* Open/close the terminal capture file. */
  2362.  
  2363.         case MEN_CAPTURE_TO_FILE:
  2364.  
  2365.             if(FileCapture)
  2366.                 CloseFileCapture();
  2367.             else
  2368.                 OpenFileCapture(FALSE);
  2369.  
  2370.             break;
  2371.  
  2372.             /* Open/close the terminal capture file. */
  2373.  
  2374.         case MEN_CAPTURE_TO_RAW_FILE:
  2375.  
  2376.             if(FileCapture)
  2377.                 CloseFileCapture();
  2378.             else
  2379.                 OpenFileCapture(TRUE);
  2380.  
  2381.             break;
  2382.  
  2383.             /* Start/terminate the printer
  2384.              * capture.
  2385.              */
  2386.  
  2387.         case MEN_CAPTURE_TO_PRINTER:
  2388.  
  2389.             if(PrinterCapture)
  2390.                 ClosePrinterCapture(TRUE);
  2391.             else
  2392.                 OpenPrinterCapture(FALSE);
  2393.  
  2394.             break;
  2395.  
  2396.             /* Iconify the program. */
  2397.  
  2398.         case MEN_ICONIFY:
  2399.  
  2400.             if(Config -> MiscConfig -> ProtectiveMode)
  2401.             {
  2402.                 ObtainSemaphore(&OnlineSemaphore);
  2403.  
  2404.                 if(Online && Config -> MiscConfig -> ReleaseDevice && !(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  2405.                 {
  2406.                     ReleaseSemaphore(&OnlineSemaphore);
  2407.  
  2408.                     BlockWindows();
  2409.  
  2410.                     if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2411.                     {
  2412.                         ReleaseWindows();
  2413.  
  2414.                         break;
  2415.                     }
  2416.  
  2417.                     ReleaseWindows();
  2418.                 }
  2419.                 else
  2420.                     ReleaseSemaphore(&OnlineSemaphore);
  2421.             }
  2422.  
  2423.             DoIconify = TRUE;
  2424.  
  2425.             break;
  2426.  
  2427.             /* Say who we are. */
  2428.  
  2429.         case MEN_ABOUT:
  2430.  
  2431.             BlockWindows();
  2432. #ifdef DATAFEED
  2433.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2434.             {
  2435.                 STATIC UBYTE LastFile[40],LastPath[256];
  2436.  
  2437.                 extern BPTR DataFeed;
  2438.  
  2439.                 if(DataFeed)
  2440.                 {
  2441.                     Close(DataFeed);
  2442.  
  2443.                     DataFeed = NULL;
  2444.                 }
  2445.  
  2446.                 if(FileRequest = GetFile(Window,"Select terminal test file",LastPath,LastFile,DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SELECT_TXT),FALSE))
  2447.                 {
  2448.                     if(GetFileSize(DummyBuffer))
  2449.                     {
  2450.                         if(DataFeed = Open(DummyBuffer,MODE_OLDFILE))
  2451.                         {
  2452.                             strcpy(LastFile,FileRequest -> fr_File);
  2453.                             strcpy(LastPath,FileRequest -> fr_Drawer);
  2454.  
  2455.                             if(Kick30)
  2456.                                 SetVBuf(DataFeed,NULL,2,8192);
  2457.                         }
  2458.                     }
  2459.  
  2460.                     FreeAslRequest(FileRequest);
  2461.                 }
  2462.             }
  2463.             else
  2464. #endif    /* DATAFEED */
  2465.  
  2466.             ShowAbout(FALSE);
  2467.  
  2468.             ReleaseWindows();
  2469.  
  2470.             break;
  2471.  
  2472.             /* Terminate the program. */
  2473.  
  2474.         case MEN_QUIT:
  2475.  
  2476.             if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  2477.                 MainTerminated = TRUE;
  2478.             else
  2479.             {
  2480.                 STRPTR    Buffer;
  2481.                 LONG    OldLen,Len = strlen(LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT)) + 3;
  2482.  
  2483.                 OldLen = Len;
  2484.  
  2485.                 ObtainSemaphore(&OnlineSemaphore);
  2486.  
  2487.                 if(Online)
  2488.                     Len += strlen(LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT)) + 4;
  2489.  
  2490.                 ReleaseSemaphore(&OnlineSemaphore);
  2491.  
  2492.                 if(BufferChanged)
  2493.                     Len += strlen(LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT)) + 4;
  2494.  
  2495.                 if(ConfigChanged)
  2496.                     Len += strlen(LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT)) + 4;
  2497.  
  2498.                 if(PhonebookChanged)
  2499.                     Len += strlen(LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT)) + 4;
  2500.  
  2501.                 if(TranslationChanged)
  2502.                     Len += strlen(LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT)) + 4;
  2503.  
  2504.                 if(MacroChanged)
  2505.                     Len += strlen(LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT)) + 4;
  2506.  
  2507.                 if(CursorKeysChanged)
  2508.                     Len += strlen(LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT)) + 4;
  2509.  
  2510.                 if(FastMacrosChanged)
  2511.                     Len += strlen(LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT)) + 4;
  2512.  
  2513.                 if(HotkeysChanged)
  2514.                     Len += strlen(LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT)) + 4;
  2515.  
  2516.                 if(SpeechChanged)
  2517.                     Len += strlen(LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT)) + 4;
  2518.  
  2519.                 if(SoundChanged)
  2520.                     Len += strlen(LocaleString(MSG_WAIT_SOUND_SETTINGS_CHANGED_TXT)) + 4;
  2521.  
  2522.                 BlockWindows();
  2523.  
  2524.                 OldPtr = ThisProcess -> pr_WindowPtr;
  2525.  
  2526.                 ThisProcess -> pr_WindowPtr = (APTR)Window;
  2527.  
  2528.                 if(OldLen != Len)
  2529.                 {
  2530.                     if(Buffer = (STRPTR)AllocVecPooled(Len,MEMF_ANY))
  2531.                     {
  2532.                         SPrintf(Buffer,"%s\n\n",LocaleString(MSG_TERMMAIN_REALLY_QUIT_TXT));
  2533.  
  2534.                         ObtainSemaphore(&OnlineSemaphore);
  2535.  
  2536.                         if(Online)
  2537.                         {
  2538.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PROGRAM_IS_STILL_ONLINE_TXT));
  2539.  
  2540.                             strcat(Buffer,SharedBuffer);
  2541.                         }
  2542.  
  2543.                         ReleaseSemaphore(&OnlineSemaphore);
  2544.  
  2545.                         if(BufferChanged)
  2546.                         {
  2547.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_REVIEW_BUFFER_NOT_SAVED_TXT));
  2548.  
  2549.                             strcat(Buffer,SharedBuffer);
  2550.                         }
  2551.  
  2552.                         if(ConfigChanged)
  2553.                         {
  2554.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CONFIGURATION_HAS_BEEN_CHANGED_TXT));
  2555.  
  2556.                             strcat(Buffer,SharedBuffer);
  2557.                         }
  2558.  
  2559.                         if(PhonebookChanged)
  2560.                         {
  2561.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_PHONEBOOK_NOT_SAVED_TXT));
  2562.  
  2563.                             strcat(Buffer,SharedBuffer);
  2564.                         }
  2565.  
  2566.                         if(TranslationChanged)
  2567.                         {
  2568.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_TRANSLATION_TABLES_CHANGED_TXT));
  2569.  
  2570.                             strcat(Buffer,SharedBuffer);
  2571.                         }
  2572.  
  2573.                         if(MacroChanged)
  2574.                         {
  2575.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_MACRO_KEYS_CHANGED_TXT));
  2576.  
  2577.                             strcat(Buffer,SharedBuffer);
  2578.                         }
  2579.  
  2580.                         if(CursorKeysChanged)
  2581.                         {
  2582.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_CURSOR_KEYS_CHANGED_TXT));
  2583.  
  2584.                             strcat(Buffer,SharedBuffer);
  2585.                         }
  2586.  
  2587.                         if(FastMacrosChanged)
  2588.                         {
  2589.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_FAST_MACROS_CHANGED_TXT));
  2590.  
  2591.                             strcat(Buffer,SharedBuffer);
  2592.                         }
  2593.  
  2594.                         if(HotkeysChanged)
  2595.                         {
  2596.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_HOTKEYS_CHANGED_TXT));
  2597.  
  2598.                             strcat(Buffer,SharedBuffer);
  2599.                         }
  2600.  
  2601.                         if(SpeechChanged)
  2602.                         {
  2603.                             SPrintf(SharedBuffer," · %s\n",LocaleString(MSG_WAIT_SPEECH_SETTINGS_CHANGED_TXT));
  2604.  
  2605.                             strcat(Buffer,SharedBuffer);
  2606.                         }
  2607.  
  2608.                         if(MyEasyRequest(Window,Buffer,LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  2609.                             MainTerminated = TRUE;
  2610.  
  2611.                         FreeVecPooled(Buffer);
  2612.                     }
  2613.                     else
  2614.                         MainTerminated = TRUE;
  2615.                 }
  2616.                 else
  2617.                     MainTerminated = TRUE;
  2618.  
  2619.                 ThisProcess -> pr_WindowPtr = OldPtr;
  2620.  
  2621.                 ReleaseWindows();
  2622.             }
  2623.  
  2624.             break;
  2625.  
  2626.             /* Feed the contents of the clipboard
  2627.              * into the input stream.
  2628.              */
  2629.  
  2630.         case MEN_PASTE:
  2631.  
  2632.             if(!OpenClip(Config -> ClipConfig -> ClipboardUnit))
  2633.             {
  2634.                 ClipInput = TRUE;
  2635.  
  2636.                 if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2637.                     ClipXerox = TRUE;
  2638.             }
  2639.             else
  2640.                 ClipInput = FALSE;
  2641.  
  2642.             break;
  2643.  
  2644.         case MEN_COPY:
  2645.  
  2646.             if(Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  2647.                 ClipMarker(TRUE);
  2648.             else
  2649.                 ClipMarker(FALSE);
  2650.  
  2651.             break;
  2652.  
  2653.         case MEN_CLEAR:
  2654.  
  2655.             DropMarker();
  2656.             break;
  2657.  
  2658.             /* Execute an AmigaDOS command. */
  2659.  
  2660.         case MEN_EXECUTE_DOS_COMMAND:
  2661.  
  2662.             BlockWindows();
  2663.  
  2664.                 /* Enter the name of the command. */
  2665.  
  2666.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AMIGADOS_COMMAND_TXT),AmigaDOSCommandBuffer))
  2667.                 SendAmigaDOSCommand(AmigaDOSCommandBuffer);
  2668.  
  2669.             ReleaseWindows();
  2670.  
  2671.             break;
  2672.  
  2673.             /* Execute an ARexx script command. */
  2674.  
  2675.         case MEN_EXECUTE_REXX_COMMAND:
  2676.  
  2677.             BlockWindows();
  2678.  
  2679.                 /* Get the rexx file name/program. */
  2680.  
  2681.             if(GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_AREXX_COMMAND_TXT),ARexxCommandBuffer))
  2682.                 SendARexxCommand(ARexxCommandBuffer,TRUE);
  2683.  
  2684.             ReleaseWindows();
  2685.  
  2686.             break;
  2687.  
  2688.             /* Turn recording on/off. */
  2689.  
  2690.         case MEN_RECORD:
  2691.  
  2692.             if(GetItem(MEN_RECORD))
  2693.             {
  2694.                 if(!Recording)
  2695.                 {
  2696.                     if(CreateRecord(CurrentBBSName[0] ? CurrentBBSName : LocaleString(MSG_SCREENPANEL_UNKNOWN_TXT)))
  2697.                     {
  2698.                         RememberResetOutput();
  2699.                         RememberResetInput();
  2700.  
  2701.                         RememberOutput = TRUE;
  2702.  
  2703.                         Recording = TRUE;
  2704.                         RecordingLine = FALSE;
  2705.  
  2706.                         OnItem(MEN_RECORD_LINE);
  2707.                     }
  2708.                 }
  2709.             }
  2710.             else
  2711.             {
  2712.                 if(Recording)
  2713.                 {
  2714.                     FinishRecord();
  2715.  
  2716.                     RememberOutput = FALSE;
  2717.                     RememberInput = FALSE;
  2718.  
  2719.                     Recording = FALSE;
  2720.                     RecordingLine = FALSE;
  2721.  
  2722.                     OffItem(MEN_RECORD_LINE);
  2723.  
  2724.                     Status = STATUS_READY;
  2725.                 }
  2726.             }
  2727.  
  2728.             break;
  2729.  
  2730.         case MEN_RECORD_LINE:
  2731.  
  2732.             if(Recording)
  2733.             {
  2734.                 if(GetItem(MEN_RECORD))
  2735.                 {
  2736.                     if(!RecordingLine)
  2737.                     {
  2738.                         RecordingLine = TRUE;
  2739.  
  2740.                         RememberResetInput();
  2741.  
  2742.                         RememberOutput = FALSE;
  2743.                         RememberInput = TRUE;
  2744.                     }
  2745.                 }
  2746.                 else
  2747.                 {
  2748.                     if(RecordingLine)
  2749.                     {
  2750.                         RememberSpill();
  2751.  
  2752.                         RecordingLine = FALSE;
  2753.  
  2754.                         RememberOutput = TRUE;
  2755.                         RememberInput = FALSE;
  2756.                     }
  2757.                 }
  2758.             }
  2759.  
  2760.             break;
  2761.  
  2762.         case MEN_DISABLE_TRAPS:
  2763.  
  2764.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2765.             {
  2766.                 ObtainSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2767.  
  2768.                 if(!(Item -> Flags & CHECKED) && GenericListTable[GLIST_TRAP] -> ListHeader . mlh_Head -> mln_Succ)
  2769.                     WatchTraps = TRUE;
  2770.                 else
  2771.                     WatchTraps = FALSE;
  2772.  
  2773.                 ReleaseSemaphore(&GenericListTable[GLIST_TRAP] -> ListSemaphore);
  2774.             }
  2775.  
  2776.             break;
  2777.  
  2778.             /* Edit the trap settings? */
  2779.  
  2780.         case MEN_EDIT_TRAPS:
  2781.  
  2782.             BlockWindows();
  2783.  
  2784.             TrapPanel();
  2785.  
  2786.             if(Item = FindThisItem(Menu,MEN_DISABLE_TRAPS))
  2787.             {
  2788.                 if(WatchTraps)
  2789.                     Item -> Flags &= ~CHECKED;
  2790.                 else
  2791.                     Item -> Flags |= CHECKED;
  2792.             }
  2793.  
  2794.             ReleaseWindows();
  2795.  
  2796.             break;
  2797.  
  2798.             /* Set the name we will use to open the
  2799.              * default console output window for
  2800.              * AmigaDOS commands and ARexx scripts.
  2801.              */
  2802.  
  2803.         case MEN_SET_CONSOLE:
  2804.  
  2805.             BlockWindows();
  2806.  
  2807.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_SET_CONSOLE_WINDOW_TXT),WindowName))
  2808.                 SetEnvDOS("TERMWINDOW",WindowName);
  2809.  
  2810.             ReleaseWindows();
  2811.  
  2812.             break;
  2813.  
  2814.             /* Open the phonebook and dial the
  2815.              * list of entries the user will select.
  2816.              */
  2817.  
  2818.         case MEN_PHONEBOOK:
  2819.  
  2820.             BlockWindows();
  2821.  
  2822.             HandleLocalDialList(TRUE);
  2823.  
  2824.             while(PhonePanel(Qualifier))
  2825.             {
  2826.                 if(!DialPanel())
  2827.                 {
  2828.                     Status = OldStatus;
  2829.  
  2830.                     break;
  2831.                 }
  2832.  
  2833.                 Status = OldStatus;
  2834.             }
  2835.  
  2836.             if(!PhonebookAutoExit)
  2837.                 KeepRedialing = FALSE;
  2838.  
  2839.             SetRedialMenu();
  2840.  
  2841.             ReleaseWindows();
  2842.  
  2843.             break;
  2844.  
  2845.             /* Redial those dial list entries which
  2846.              * we were unable to connect.
  2847.              */
  2848.  
  2849.         case MEN_REDIAL:
  2850.  
  2851.             BlockWindows();
  2852.  
  2853.                 /* If the modem is still online, provide help. */
  2854.  
  2855.             if(!AskDial(Window))
  2856.             {
  2857.                 ReleaseWindows();
  2858.                 break;
  2859.             }
  2860.  
  2861.             HandleLocalDialList(TRUE);
  2862.  
  2863.             do
  2864.             {
  2865.                 if(!DialPanel())
  2866.                 {
  2867.                     KeepRedialing = FALSE;
  2868.  
  2869.                     Status = OldStatus;
  2870.  
  2871.                     break;
  2872.                 }
  2873.  
  2874.                 Status = OldStatus;
  2875.             }
  2876.             while(PhonePanel(NULL));
  2877.  
  2878.             if(!PhonebookAutoExit)
  2879.                 KeepRedialing = FALSE;
  2880.  
  2881.             SetRedialMenu();
  2882.  
  2883.             ReleaseWindows();
  2884.  
  2885.             break;
  2886.  
  2887.             /* Dial a single number. */
  2888.  
  2889.         case MEN_DIAL_NUMBER:
  2890.  
  2891.             BlockWindows();
  2892.  
  2893.                 /* If the modem is still online, provide help. */
  2894.  
  2895.             if(!AskDial(Window))
  2896.             {
  2897.                 ReleaseWindows();
  2898.                 break;
  2899.             }
  2900.  
  2901.             HandleLocalDialList(TRUE);
  2902.  
  2903.             if(GetString(FALSE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_PHONE_NUMBER_TXT),DialNumberBuffer))
  2904.             {
  2905.                 if(DialNumberBuffer[0])
  2906.                 {
  2907.                     struct List *LocalList;
  2908.  
  2909.                     if(LocalList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
  2910.                     {
  2911.                         struct PhoneNode    *DialNode;
  2912.                         LONG             Len = strlen(DialNumberBuffer);
  2913.  
  2914.                         NewList(LocalList);
  2915.  
  2916.                         if(DialNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode) + Len + 1,MEMF_ANY|MEMF_CLEAR))
  2917.                         {
  2918.                             DialNode -> VanillaNode . ln_Name = (char *)(DialNode + 1);
  2919.  
  2920.                             strcpy(DialNode -> VanillaNode . ln_Name,DialNumberBuffer);
  2921.  
  2922.                             AddTail(LocalList,&DialNode -> VanillaNode);
  2923.  
  2924.                             FreeDialList(TRUE);
  2925.  
  2926.                             DialList = LocalList;
  2927.  
  2928.                             DialPanel();
  2929.  
  2930.                             Status = OldStatus;
  2931.                         }
  2932.                         else
  2933.                             FreeVecPooled(LocalList);
  2934.                     }
  2935.                 }
  2936.             }
  2937.  
  2938.             SetRedialMenu();
  2939.  
  2940.             ReleaseWindows();
  2941.  
  2942.             break;
  2943.  
  2944.             /* Send a break across the serial line. */
  2945.  
  2946.         case MEN_SEND_BREAK:
  2947.  
  2948.             SendBreak();
  2949.             break;
  2950.  
  2951.             /* Hang up the phone line. */
  2952.  
  2953.         case MEN_HANG_UP:
  2954.  
  2955.             FullHangup(FALSE);
  2956.  
  2957.             break;
  2958.  
  2959.             /* Wait a bit... */
  2960.  
  2961.         case MEN_WAIT:
  2962.         {
  2963.             struct Window        *ReqWindow;
  2964.             struct EasyStruct     Easy;
  2965.  
  2966.             Easy . es_StructSize    = sizeof(struct EasyStruct);
  2967.             Easy . es_Flags        = NULL;
  2968.             Easy . es_Title        = (UBYTE *)LocaleString(MSG_TERMAUX_TERM_REQUEST_TXT);
  2969.             Easy . es_GadgetFormat    = (UBYTE *)LocaleString(MSG_GLOBAL_CONTINUE_TXT);
  2970.             Easy . es_TextFormat    = (UBYTE *)LocaleString(MSG_TERMMAIN_WAITING_TXT);
  2971.  
  2972.             BlockWindows();
  2973.  
  2974.             if(ReqWindow = BuildEasyRequest(Window,&Easy,IDCMP_RAWKEY,NULL))
  2975.             {
  2976.                 ULONG    Signals;
  2977.                 BYTE    Done = FALSE;
  2978.  
  2979.                     /* Don't echo serial output. */
  2980.  
  2981.                 Quiet = TRUE;
  2982.  
  2983.                 do
  2984.                 {
  2985.                     SerWrite(" \b",2);
  2986.  
  2987.                     HandleSerial();
  2988.  
  2989.                     StartTime(1,0);
  2990.  
  2991.                     Signals = Wait(SIG_TIMER | PORTMASK(ReqWindow -> UserPort));
  2992.  
  2993.                     if(Signals & SIG_TIMER)
  2994.                         WaitIO(TimeRequest);
  2995.  
  2996.                     if(Signals & PORTMASK(ReqWindow -> UserPort))
  2997.                     {
  2998.                         LONG    Result;
  2999.                         ULONG    IDCMP = NULL;
  3000.  
  3001.                         Result = SysReqHandler(ReqWindow,&IDCMP,FALSE);
  3002.  
  3003.                         if(Result == 0 || (Result == -2 && !(IDCMP & IDCMP_RAWKEY)))
  3004.                         {
  3005.                             if(!CheckIO(TimeRequest))
  3006.                                 AbortIO(TimeRequest);
  3007.  
  3008.                             WaitIO(TimeRequest);
  3009.  
  3010.                             Done = TRUE;
  3011.                         }
  3012.                     }
  3013.                 }
  3014.                 while(!Done);
  3015.  
  3016.                 Quiet = FALSE;
  3017.  
  3018.                 FreeSysRequest(ReqWindow);
  3019.             }
  3020.  
  3021.             ReleaseWindows();
  3022.         }
  3023.  
  3024.         break;
  3025.  
  3026.             /* Flush the serial buffers. */
  3027.  
  3028.         case MEN_FLUSH_BUFFER:
  3029.  
  3030.             ClearSerial();
  3031.  
  3032.             RestartSerial();
  3033.  
  3034.             break;
  3035.  
  3036.             /* Release the serial device for other
  3037.              * applications.
  3038.              */
  3039.  
  3040.         case MEN_RELEASE_DEVICE:
  3041.  
  3042.             ReleaseSerial = TRUE;
  3043.             break;
  3044.  
  3045.         case MEN_UPLOAD_ASCII:
  3046.  
  3047.             BlockWindows();
  3048.  
  3049.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  3050.             {
  3051.                 BinaryTransfer = FALSE;
  3052.  
  3053.                 StartXprSend(TRANSFER_ASCII,TRUE);
  3054.  
  3055.                 BinaryTransfer = TRUE;
  3056.             }
  3057.  
  3058.             ResetProtocol();
  3059.  
  3060.             ReleaseWindows();
  3061.  
  3062.             break;
  3063.  
  3064.         case MEN_DOWNLOAD_ASCII:
  3065.  
  3066.             BlockWindows();
  3067.  
  3068.             if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  3069.             {
  3070.                 BinaryTransfer = FALSE;
  3071.  
  3072.                 StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  3073.  
  3074.                 BinaryTransfer = TRUE;
  3075.             }
  3076.  
  3077.             ResetProtocol();
  3078.  
  3079.             ReleaseWindows();
  3080.  
  3081.             break;
  3082.  
  3083.         case MEN_UPLOAD_TEXT:
  3084.  
  3085.             BlockWindows();
  3086.  
  3087.             if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  3088.             {
  3089.                 BinaryTransfer = FALSE;
  3090.  
  3091.                 StartXprSend(TRANSFER_TEXT,TRUE);
  3092.  
  3093.                 BinaryTransfer = TRUE;
  3094.             }
  3095.  
  3096.             ResetProtocol();
  3097.  
  3098.             ReleaseWindows();
  3099.  
  3100.             break;
  3101.  
  3102.         case MEN_DOWNLOAD_TEXT:
  3103.  
  3104.             BlockWindows();
  3105.  
  3106.             if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  3107.             {
  3108.                 BinaryTransfer = FALSE;
  3109.  
  3110.                 StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  3111.  
  3112.                 BinaryTransfer = TRUE;
  3113.             }
  3114.  
  3115.             ResetProtocol();
  3116.  
  3117.             ReleaseWindows();
  3118.  
  3119.             break;
  3120.  
  3121.             /* Edit and transfer a file. */
  3122.  
  3123.         case MEN_EDIT_AND_UPLOAD_TEXT:
  3124.  
  3125.             BlockWindows();
  3126.  
  3127.             if(!Config -> PathConfig -> Editor[0])
  3128.                 GetString(TRUE,FALSE,0,LocaleString(MSG_TERMMAIN_ENTER_NAME_OF_EDITOR_TO_USE_TXT),Config -> PathConfig -> Editor);
  3129.  
  3130.             if(Config -> PathConfig -> Editor[0])
  3131.             {
  3132.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_EDIT_AND_TRANSFER_FILE_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_TERMMAIN_EDIT_TXT),TRUE))
  3133.                 {
  3134.                     UBYTE CompoundName[512];
  3135.  
  3136.                     strcpy(CompoundName,Config -> PathConfig -> Editor);
  3137.                     strcat(CompoundName," \"");
  3138.                     strcat(CompoundName,DummyBuffer);
  3139.                     strcat(CompoundName,"\"");
  3140.  
  3141.                     LaunchCommand(CompoundName);
  3142.  
  3143.                     BumpWindow(Window);
  3144.  
  3145.                     FreeAslRequest(FileRequest);
  3146.  
  3147.                     if(GetFileSize(DummyBuffer))
  3148.                     {
  3149.                         BinaryTransfer = FALSE;
  3150.  
  3151.                         switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILE_AS_TXT),LocaleString(MSG_TERMMAIN_ASCII_UPLOAD_CANCEL_TXT),FilePart(DummyBuffer)))
  3152.                         {
  3153.                             case 1:    if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  3154.                                     SendTextFile(TRANSFER_ASCII,DummyBuffer);
  3155.  
  3156.                                 ResetProtocol();
  3157.  
  3158.                                 break;
  3159.  
  3160.                             case 2:    if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  3161.                                     SendTextFile(TRANSFER_TEXT,DummyBuffer);
  3162.  
  3163.                                 ResetProtocol();
  3164.  
  3165.                                 break;
  3166.                         }
  3167.  
  3168.                         BinaryTransfer = TRUE;
  3169.                     }
  3170.                 }
  3171.             }
  3172.  
  3173.             ReleaseWindows();
  3174.             break;
  3175.  
  3176.         case MEN_UPLOAD_BINARY:
  3177.  
  3178.             BlockWindows();
  3179.  
  3180.             if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  3181.             {
  3182.                 BinaryTransfer = TRUE;
  3183.  
  3184.                 StartXprSend(TRANSFER_BINARY,TRUE);
  3185.             }
  3186.  
  3187.             ResetProtocol();
  3188.  
  3189.             ReleaseWindows();
  3190.  
  3191.             break;
  3192.  
  3193.             /* Download some files. */
  3194.  
  3195.         case MEN_DOWNLOAD_BINARY:
  3196.  
  3197.             BlockWindows();
  3198.  
  3199.             if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  3200.             {
  3201.                 BinaryTransfer = TRUE;
  3202.  
  3203.                 StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  3204.             }
  3205.  
  3206.             ResetProtocol();
  3207.  
  3208.             ReleaseWindows();
  3209.  
  3210.             break;
  3211.  
  3212.             /* Clear the contents of the scrollback
  3213.              * buffer.
  3214.              */
  3215.  
  3216.         case MEN_CLEAR_BUFFER:
  3217.  
  3218.             if(Lines)
  3219.             {
  3220.                 BlockWindows();
  3221.  
  3222.                 if((Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) || !Config -> MiscConfig -> ProtectiveMode)
  3223.                 {
  3224.                     FreeBuffer();
  3225.  
  3226.                     TerminateBuffer();
  3227.                 }
  3228.                 else
  3229.                 {
  3230.                     if(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT),Lines))
  3231.                     {
  3232.                         FreeBuffer();
  3233.  
  3234.                         TerminateBuffer();
  3235.                     }
  3236.                 }
  3237.  
  3238.                 ReleaseWindows();
  3239.             }
  3240.  
  3241.             break;
  3242.  
  3243.             /* Display the scrollback buffer.
  3244.              * Notify the scrollback task or
  3245.              * fire it off if appropriate.
  3246.              */
  3247.  
  3248.         case MEN_DISPLAY_BUFFER:
  3249.  
  3250.             if(!LaunchBuffer())
  3251.             {
  3252.                 BlockWindows();
  3253.  
  3254.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNABLE_TO_CREATE_BUFFER_TASK_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3255.  
  3256.                 ReleaseWindows();
  3257.             }
  3258.  
  3259.             break;
  3260.  
  3261.             /* Close the buffer display. */
  3262.  
  3263.         case MEN_CLOSE_BUFFER:
  3264.  
  3265.             TerminateBuffer();
  3266.             break;
  3267.  
  3268.             /* Is the buffer to be frozen? */
  3269.  
  3270.         case MEN_FREEZE_BUFFER:
  3271.  
  3272.             if(Item = FindThisItem(Menu,MEN_FREEZE_BUFFER))
  3273.             {
  3274.                 if(Item -> Flags & CHECKED)
  3275.                     BufferFrozen = TRUE;
  3276.                 else
  3277.                     BufferFrozen = FALSE;
  3278.  
  3279.                 ConOutputUpdate();
  3280.             }
  3281.  
  3282.             break;
  3283.  
  3284.             /* Load the buffer contents from a file. */
  3285.  
  3286.         case MEN_OPEN_BUFFER:
  3287.  
  3288.             BlockWindows();
  3289.  
  3290.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_LOAD_BUFFER_TXT),"","",DummyBuffer,NULL,FALSE,FALSE,FALSE,LocaleString(MSG_GLOBAL_LOAD_TXT),FALSE))
  3291.             {
  3292.                 if(GetFileSize(DummyBuffer))
  3293.                 {
  3294.                     if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  3295.                     {
  3296.                         if(Lines)
  3297.                         {
  3298.                             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_BUFFER_STILL_HOLDS_LINES_TXT),LocaleString(MSG_TERMMAIN_DISCARD_APPPEND_CANCEL_TXT),Lines))
  3299.                             {
  3300.                                 case 1:    FreeBuffer();
  3301.                                     break;
  3302.  
  3303.                                 case 2:    break;
  3304.  
  3305.                                 case 0:    Close(SomeFile);
  3306.                                     SomeFile = NULL;
  3307.                                     break;
  3308.                             }
  3309.                         }
  3310.  
  3311.                         if(SomeFile)
  3312.                         {
  3313.                             LONG Len;
  3314.  
  3315.                             LineRead(NULL,NULL,NULL);
  3316.  
  3317.                             while((Len = LineRead(SomeFile,DummyBuffer,80)) > 0)
  3318.                                 CaptureParser(DummyBuffer,Len,AddLine);
  3319.  
  3320.                             Close(SomeFile);
  3321.  
  3322.                             BufferChanged = TRUE;
  3323.                         }
  3324.                     }
  3325.                     else
  3326.                         ShowError(Window,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  3327.                 }
  3328.  
  3329.                 FreeAslRequest(FileRequest);
  3330.             }
  3331.  
  3332.             ReleaseWindows();
  3333.             break;
  3334.  
  3335.             /* Save the contents of the scrollback
  3336.              * buffer to a file (line by line).
  3337.              */
  3338.  
  3339.         case MEN_SAVE_BUFFER_AS:
  3340.  
  3341.             BlockWindows();
  3342.  
  3343.             if(!Lines || !BufferLines)
  3344.                 MyEasyRequest(Window,LocaleString(MSG_GLOBAL_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3345.             else
  3346.             {
  3347.                 if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_BUFFER_TXT),Config -> CaptureConfig -> BufferPath,"",DummyBuffer,NULL,TRUE,FALSE,FALSE,LocaleString(MSG_GLOBAL_SAVE_TXT),FALSE))
  3348.                 {
  3349.                     LONG Error = 0;
  3350.  
  3351.                     SomeFile = NULL;
  3352.  
  3353.                         /* If the file we are about
  3354.                          * to create already exists,
  3355.                          * ask the user whether we are
  3356.                          * to create, append or skip
  3357.                          * the file.
  3358.                          */
  3359.  
  3360.                     if(GetFileSize(DummyBuffer))
  3361.                     {
  3362.                         switch(MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  3363.                         {
  3364.                             case 1:    SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3365.                                 break;
  3366.  
  3367.                             case 2:    if(SomeFile = Open(DummyBuffer,MODE_READWRITE))
  3368.                                 {
  3369.                                     if(Seek(SomeFile,0,OFFSET_END) == -1)
  3370.                                     {
  3371.                                         Close(SomeFile);
  3372.  
  3373.                                         SomeFile = NULL;
  3374.                                     }
  3375.                                 }
  3376.  
  3377.                                 break;
  3378.                         }
  3379.                     }
  3380.                     else
  3381.                         SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  3382.  
  3383.                     if(SomeFile)
  3384.                     {
  3385.                         LONG i,Len;
  3386.  
  3387.                             /* Obtain the semaphore required
  3388.                              * to gain access to the line buffer
  3389.                              */
  3390.  
  3391.                         ObtainSemaphore(BufferSemaphore);
  3392.  
  3393.                         for(i = 0 ; i < Lines ; i++)
  3394.                         {
  3395.                             Len = BufferLines[i][-1];
  3396.  
  3397.                             if(Len)
  3398.                             {
  3399.                                 SetIoErr(0);
  3400.  
  3401.                                 if(FWrite(SomeFile,BufferLines[i],Len,1) < 1)
  3402.                                 {
  3403.                                     Error = IoErr();
  3404.  
  3405.                                     break;
  3406.                                 }
  3407.                             }
  3408.  
  3409.                             SetIoErr(0);
  3410.  
  3411.                             if(FPrintf(SomeFile,"\n") < 1)
  3412.                             {
  3413.                                 Error = IoErr();
  3414.  
  3415.                                 break;
  3416.                             }
  3417.                         }
  3418.  
  3419.                         ReleaseSemaphore(BufferSemaphore);
  3420.  
  3421.                         Close(SomeFile);
  3422.  
  3423.                         AddProtection(DummyBuffer,FIBF_EXECUTE);
  3424.  
  3425.                         if(Config -> MiscConfig -> CreateIcons)
  3426.                             AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  3427.  
  3428.                         BufferChanged = FALSE;
  3429.                     }
  3430.                     else
  3431.                         Error = IoErr();
  3432.  
  3433.                     if(Error)
  3434.                         ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  3435.  
  3436.                     FreeAslRequest(FileRequest);
  3437.                 }
  3438.             }
  3439.  
  3440.             ReleaseWindows();
  3441.  
  3442.             break;
  3443.  
  3444.             /* Simply clear the screen and move the
  3445.              * cursor to its home position.
  3446.              */
  3447.  
  3448.         case MEN_CLEAR_SCREEN:
  3449.  
  3450.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3451.                 XEmulatorClearConsole(XEM_IO);
  3452.             else
  3453.             {
  3454.                 DropMarker();
  3455.  
  3456.                 ConBypass("\033[2J\033[H",-1);
  3457.             }
  3458.  
  3459.             break;
  3460.  
  3461.             /* Reset the current text rendering font. */
  3462.  
  3463.         case MEN_RESET_FONT:
  3464.  
  3465.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3466.                 XEmulatorResetCharset(XEM_IO);
  3467.             else
  3468.             {
  3469.                 DropMarker();
  3470.  
  3471.                 CurrentFont = TextFont;
  3472.  
  3473.                 SetFont(RPort,CurrentFont);
  3474.  
  3475.                 ConOutputUpdate();
  3476.             }
  3477.  
  3478.             break;
  3479.  
  3480.             /* Reset the display styles and restore
  3481.              * the colours.
  3482.              */
  3483.  
  3484.         case MEN_RESET_STYLES:
  3485.  
  3486.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3487.                 XEmulatorResetTextStyles(XEM_IO);
  3488.             else
  3489.             {
  3490.                 DropMarker();
  3491.  
  3492.                 ConBypass("\033[0m",-1);
  3493.  
  3494.                 ObtainSemaphore(&TerminalSemaphore);
  3495.  
  3496.                 ClearCursor();
  3497.  
  3498.                 CurrentCharWidth = SCALE_NORMAL;
  3499.  
  3500.                 if(!Config -> EmulationConfig -> LockColour)
  3501.                 {
  3502.                     ForegroundPen = GetPenIndex(SafeTextPen);
  3503.                     BackgroundPen = 0;
  3504.                 }
  3505.  
  3506.                 SetMask(RPort,DepthMask);
  3507.  
  3508.                 UpdatePens();
  3509.  
  3510.                 ConFontScaleUpdate();
  3511.  
  3512.                 DrawCursor();
  3513.  
  3514.                 ReleaseSemaphore(&TerminalSemaphore);
  3515.             }
  3516.  
  3517.             break;
  3518.  
  3519.             /* Reset the whole terminal. */
  3520.  
  3521.         case MEN_RESET_TERMINAL:
  3522.  
  3523.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3524.                 XEmulatorResetConsole(XEM_IO);
  3525.             else
  3526.             {
  3527.                 FreeMarker();
  3528.  
  3529.                 ConBypass("\033c",-1);
  3530.             }
  3531.  
  3532.             break;
  3533.  
  3534.         case MEN_SET_EMULATION:
  3535.  
  3536.             BlockWindows();
  3537.  
  3538.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3539.             {
  3540.                 OptionTitle = LocaleString(MSG_TERMMAIN_EMULATION_PREFERENCES_TXT);
  3541.  
  3542.                 NewOptions = FALSE;
  3543.  
  3544.                 XEmulatorOptions(XEM_IO);
  3545.  
  3546.                 if(NewOptions)
  3547.                 {
  3548.                     SetEmulatorOptions(XEM_PREFS_SAVE);
  3549.  
  3550.                     NewOptions = FALSE;
  3551.                 }
  3552.  
  3553.                 OptionTitle = NULL;
  3554.             }
  3555.             else
  3556.             {
  3557.                 if(EmulationPanel(Config,NULL))
  3558.                 {
  3559.                     ConfigSetup();
  3560.  
  3561.                     ConfigChanged = TRUE;
  3562.                 }
  3563.             }
  3564.  
  3565.             ReleaseWindows();
  3566.  
  3567.             break;
  3568.  
  3569.             /* Set the serial preferences. */
  3570.  
  3571.         case MEN_SERIAL:
  3572.  
  3573.             BlockWindows();
  3574.  
  3575.             if(SerialPanel(Config,NULL))
  3576.             {
  3577.                 ConfigSetup();
  3578.  
  3579.                 ConfigChanged = TRUE;
  3580.             }
  3581.  
  3582.             ReleaseWindows();
  3583.  
  3584.             break;
  3585.  
  3586.             /* Set the modem preferences. */
  3587.  
  3588.         case MEN_MODEM:
  3589.  
  3590.             BlockWindows();
  3591.  
  3592.             if(ModemPanel(Config,NULL))
  3593.             {
  3594.                 FlowInit(TRUE);
  3595.  
  3596.                 ConfigChanged = TRUE;
  3597.             }
  3598.  
  3599.             ReleaseWindows();
  3600.  
  3601.             break;
  3602.  
  3603.             /* Set the screen preferences. */
  3604.  
  3605.         case MEN_SCREEN:
  3606.  
  3607.             BlockWindows();
  3608.  
  3609.             if(ScreenPanel(Config,NULL))
  3610.             {
  3611.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3612.                 {
  3613.                     switch(Config -> ScreenConfig -> ColourMode)
  3614.                     {
  3615.                         case COLOUR_EIGHT:
  3616.  
  3617.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3618.                             break;
  3619.  
  3620.                         case COLOUR_SIXTEEN:
  3621.  
  3622.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3623.                             break;
  3624.  
  3625.                         case COLOUR_AMIGA:
  3626.  
  3627.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3628.                             break;
  3629.  
  3630.                         case COLOUR_MONO:
  3631.  
  3632.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3633.                             break;
  3634.                     }
  3635.                 }
  3636.  
  3637.                 ConfigSetup();
  3638.  
  3639.                 ConfigChanged = TRUE;
  3640.             }
  3641.             else
  3642.             {
  3643.                 if(memcmp(PrivateConfig -> ScreenConfig -> Colours,Config -> ScreenConfig -> Colours,sizeof(UWORD) * 16))
  3644.                 {
  3645.                     switch(Config -> ScreenConfig -> ColourMode)
  3646.                     {
  3647.                         case COLOUR_EIGHT:
  3648.  
  3649.                             CopyMem(Config -> ScreenConfig -> Colours,ANSIColours,16 * sizeof(UWORD));
  3650.                             break;
  3651.  
  3652.                         case COLOUR_SIXTEEN:
  3653.  
  3654.                             CopyMem(Config -> ScreenConfig -> Colours,EGAColours,16 * sizeof(UWORD));
  3655.                             break;
  3656.  
  3657.                         case COLOUR_AMIGA:
  3658.  
  3659.                             CopyMem(Config -> ScreenConfig -> Colours,DefaultColours,16 * sizeof(UWORD));
  3660.                             break;
  3661.  
  3662.                         case COLOUR_MONO:
  3663.  
  3664.                             CopyMem(Config -> ScreenConfig -> Colours,AtomicColours,16 * sizeof(UWORD));
  3665.                             break;
  3666.                     }
  3667.  
  3668.                     ConfigChanged = TRUE;
  3669.                 }
  3670.             }
  3671.  
  3672.             ReleaseWindows();
  3673.  
  3674.             break;
  3675.  
  3676.             /* Set the terminal preferences. */
  3677.  
  3678.         case MEN_TERMINAL:
  3679.  
  3680.             BlockWindows();
  3681.  
  3682.             if(TerminalPanel(Config,NULL))
  3683.             {
  3684.                 Update_CR_LF_Translation();
  3685.  
  3686.                 ConfigSetup();
  3687.  
  3688.                 ConfigChanged = TRUE;
  3689.             }
  3690.  
  3691.             ReleaseWindows();
  3692.  
  3693.             break;
  3694.  
  3695.             /* Set the clipboard preferences. */
  3696.  
  3697.         case MEN_CLIPBOARD:
  3698.  
  3699.             BlockWindows();
  3700.  
  3701.             if(ClipPanel(Config,NULL))
  3702.             {
  3703.                 ConfigSetup();
  3704.  
  3705.                 ConfigChanged = TRUE;
  3706.             }
  3707.  
  3708.             ReleaseWindows();
  3709.  
  3710.             break;
  3711.  
  3712.             /* Set the capture preferences. */
  3713.  
  3714.         case MEN_CAPTURE:
  3715.  
  3716.             BlockWindows();
  3717.  
  3718.             if(CapturePanel(Config,NULL))
  3719.             {
  3720.                 ConOutputUpdate();
  3721.  
  3722.                 ConfigSetup();
  3723.  
  3724.                 ConfigChanged = TRUE;
  3725.             }
  3726.  
  3727.             ReleaseWindows();
  3728.  
  3729.             break;
  3730.  
  3731.             /* Set the command preferences. */
  3732.  
  3733.         case MEN_COMMANDS:
  3734.  
  3735.             BlockWindows();
  3736.  
  3737.             if(CommandPanel(Config,NULL))
  3738.                 ConfigChanged = TRUE;
  3739.  
  3740.             ReleaseWindows();
  3741.  
  3742.             break;
  3743.  
  3744.             /* Set the miscellaneous preferences. */
  3745.  
  3746.         case MEN_MISC:
  3747.  
  3748.             BlockWindows();
  3749.  
  3750.             if(MiscPanel(Config,NULL))
  3751.             {
  3752.                 ConfigSetup();
  3753.  
  3754.                 ConfigChanged = TRUE;
  3755.             }
  3756.  
  3757.             ReleaseWindows();
  3758.  
  3759.             break;
  3760.  
  3761.             /* Set the path settings. */
  3762.  
  3763.         case MEN_PATH:
  3764.  
  3765.             BlockWindows();
  3766.  
  3767.             if(PathPanel(Config,NULL))
  3768.                 ConfigChanged = TRUE;
  3769.  
  3770.             ReleaseWindows();
  3771.  
  3772.             break;
  3773.  
  3774.             /* Set the file transfer options. */
  3775.  
  3776.         case MEN_TRANSFER:
  3777.  
  3778.             BlockWindows();
  3779.  
  3780.             XprIO -> xpr_filename = NULL;
  3781.  
  3782.                 /* Set up the library options. */
  3783.  
  3784.             if(XProtocolBase)
  3785.             {
  3786.                 XPRCommandSelected = FALSE;
  3787.  
  3788. #ifdef ASYNC_XPR_SREAD
  3789.                 ClearSerial();
  3790. #endif
  3791.                 NewOptions = FALSE;
  3792.  
  3793.                 TransferBits = XProtocolSetup(XprIO);
  3794.  
  3795. #ifdef ASYNC_XPR_SREAD
  3796.                 RestartSerial();
  3797. #endif
  3798.                 DeleteTransferPanel(TRUE);
  3799.  
  3800.                     /* Successful? */
  3801.  
  3802. /*                if(!XPRCommandSelected)*/
  3803.                 {
  3804.                     if(!(TransferBits & XPRS_SUCCESS))
  3805.                     {
  3806.                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LastXprLibrary);
  3807.  
  3808.                         CloseLibrary(XProtocolBase);
  3809.  
  3810.                         XProtocolBase = NULL;
  3811.  
  3812.                         LastXprLibrary[0] = 0;
  3813.  
  3814.                         TransferBits = 0;
  3815.  
  3816.                         SetTransferMenu(TRUE);
  3817.                     }
  3818.                     else
  3819.                         SaveProtocolOpts();
  3820.                 }
  3821.             }
  3822.  
  3823.             ReleaseWindows();
  3824.  
  3825.             break;
  3826.  
  3827.             /* Set the file transfer procol settings. */
  3828.  
  3829.         case MEN_TRANSFER_PROTOCOL:
  3830.  
  3831.             BlockWindows();
  3832.  
  3833.             if(LibPanel(Config,NULL))
  3834.             {
  3835.                 ConfigSetup();
  3836.  
  3837.                 ConfigChanged = TRUE;
  3838.  
  3839.                 FlowInit(TRUE);
  3840.             }
  3841.  
  3842.             ReleaseWindows();
  3843.  
  3844.             break;
  3845.  
  3846.             /* Set the translation tables. */
  3847.  
  3848.         case MEN_TRANSLATION:
  3849.  
  3850.             BlockWindows();
  3851.  
  3852.             TranslationChanged |= TranslationPanel(&SendTable,&ReceiveTable,LastTranslation,Window,&TranslationChanged);
  3853.  
  3854.                 /* Choose the right console write routine. */
  3855.  
  3856.             ConOutputUpdate();
  3857.  
  3858.             ReleaseWindows();
  3859.  
  3860.             break;
  3861.  
  3862.             /* Set the keyboard macros. */
  3863.  
  3864.         case MEN_MACROS:
  3865.  
  3866.             BlockWindows();
  3867.  
  3868.             if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  3869.             {
  3870.                 XEmulatorMacroKeyFilter(XEM_IO,NULL);
  3871.  
  3872.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window,&MacroChanged);
  3873.  
  3874.                 SetupXEM_MacroKeys(MacroKeys);
  3875.             }
  3876.             else
  3877.                 MacroChanged |= MacroPanel(MacroKeys,LastMacros,TRUE,Window,&MacroChanged);
  3878.  
  3879.             ReleaseWindows();
  3880.  
  3881.             break;
  3882.  
  3883.             /* Set the cursor keys. */
  3884.  
  3885.         case MEN_CURSORKEYS:
  3886.  
  3887.             BlockWindows();
  3888.  
  3889.             CursorKeysChanged |= CursorPanel(CursorKeys,LastCursorKeys,Window,&CursorKeysChanged);
  3890.  
  3891.             ReleaseWindows();
  3892.  
  3893.             break;
  3894.  
  3895.             /* Set the fast macros. */
  3896.  
  3897.         case MEN_FAST_MACROS:
  3898.  
  3899.             BlockWindows();
  3900.  
  3901.                 // Looks weird, doesn't it?  Actually, it's quite harmless. If FastMacroPanel()
  3902.                 // returns TRUE, FastMacrosChanged won't be modified. If FastMacrosChanged is
  3903.                 // modified, it will always be set to FALSE and FastMacroPanel() will also return
  3904.                 // FALSE.
  3905.  
  3906.             FastMacrosChanged |= FastMacroPanel(&FastMacroList,LastFastMacros,Window,&FastMacrosChanged);
  3907.  
  3908.             ReleaseWindows();
  3909.  
  3910.             break;
  3911.  
  3912.             /* Set the hotkey preferences. */
  3913.  
  3914.         case MEN_HOTKEYS:
  3915.  
  3916.             BlockWindows();
  3917.  
  3918.             if(HotkeyPanel(&Hotkeys,&HotkeysChanged))
  3919.             {
  3920.                 if(!SetupCx())
  3921.                     MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_SET_UP_HOTKEYS_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  3922.             }
  3923.  
  3924.             ReleaseWindows();
  3925.  
  3926.             break;
  3927.  
  3928.             /* Set the speech preferences. */
  3929.  
  3930.         case MEN_SPEECH:
  3931.  
  3932.             BlockWindows();
  3933.  
  3934.             SpeechPanel();
  3935.  
  3936.             ReleaseWindows();
  3937.  
  3938.             break;
  3939.  
  3940.             /* Set the sound preferences. */
  3941.  
  3942.         case MEN_SOUND:
  3943.  
  3944.             BlockWindows();
  3945.  
  3946.             if(SoundPanel(&SoundConfig))
  3947.                 SoundInit();
  3948.  
  3949.             ReleaseWindows();
  3950.  
  3951.             break;
  3952.  
  3953.             /* Edit the phone number patterns and rates. */
  3954.  
  3955.             /* Edit the trap settings? */
  3956.  
  3957.         case MEN_RATES:
  3958.  
  3959.             BlockWindows();
  3960.  
  3961.             PatternPanel();
  3962.  
  3963.             ReleaseWindows();
  3964.  
  3965.             break;
  3966.  
  3967.             /* Open the preferences settings. */
  3968.  
  3969.         case MEN_OPEN_SETTINGS:
  3970.  
  3971.             BlockWindows();
  3972.  
  3973.             strcpy(DummyBuffer,LastConfig);
  3974.  
  3975.             DummyChar = PathPart(DummyBuffer);
  3976.  
  3977.             *DummyChar = 0;
  3978.  
  3979.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_OPEN_PREFERENCES_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",FALSE,FALSE,FALSE,NULL,TRUE))
  3980.             {
  3981.                 if(ReadConfig(DummyBuffer,PrivateConfig))
  3982.                 {
  3983.                     SwapConfig(PrivateConfig,Config);
  3984.  
  3985.                     strcpy(LastConfig,DummyBuffer);
  3986.  
  3987.                     ConfigSetup();
  3988.  
  3989.                     ConfigChanged = FALSE;
  3990.                 }
  3991.                 else
  3992.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_ERROR_OPENING_FILE_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),DummyBuffer);
  3993.  
  3994.                 FreeAslRequest(FileRequest);
  3995.             }
  3996.  
  3997.             ReleaseWindows();
  3998.  
  3999.             break;
  4000.  
  4001.             /* Save the terminal preferences. */
  4002.  
  4003.         case MEN_SAVE_SETTINGS:
  4004.  
  4005.             if(LastConfig[0])
  4006.             {
  4007.                 BlockWindows();
  4008.  
  4009.                 if(!Screen)
  4010.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  4011.  
  4012.                 if(!WriteConfig(LastConfig,Config))
  4013.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),LastConfig);
  4014.                 else
  4015.                     ConfigChanged = FALSE;
  4016.  
  4017.                 ReleaseWindows();
  4018.  
  4019.                 break;
  4020.             }
  4021.  
  4022.             /* Save the terminal preferences to a
  4023.              * given file name.
  4024.              */
  4025.  
  4026.         case MEN_SAVE_SETTINGS_AS:
  4027.  
  4028.             BlockWindows();
  4029.  
  4030.             strcpy(DummyBuffer,LastConfig);
  4031.  
  4032.             DummyChar = PathPart(DummyBuffer);
  4033.  
  4034.             *DummyChar = 0;
  4035.  
  4036.             if(FileRequest = GetFile(Window,LocaleString(MSG_TERMMAIN_SAVE_PREFERENCES_AS_TXT),DummyBuffer,FilePart(LastConfig),DummyBuffer,"#?.prefs",TRUE,FALSE,FALSE,NULL,TRUE))
  4037.             {
  4038.                 if(!Screen)
  4039.                     PutWindowInfo(WINDOW_MAIN,Window -> LeftEdge,Window -> TopEdge,Window -> Width,Window -> Height);
  4040.  
  4041.                 if(WriteConfig(DummyBuffer,Config))
  4042.                 {
  4043.                     strcpy(LastConfig,DummyBuffer);
  4044.  
  4045.                     ConfigChanged = FALSE;
  4046.                 }
  4047.                 else
  4048.                     ShowError(Window,ERR_SAVE_ERROR,IoErr(),DummyBuffer);
  4049.  
  4050.                 FreeAslRequest(FileRequest);
  4051.             }
  4052.  
  4053.             ReleaseWindows();
  4054.  
  4055.             break;
  4056.  
  4057.             /* Show terminal information window. */
  4058.  
  4059.         case MEN_STATUS_WINDOW:
  4060.  
  4061.             if(InfoWindow)
  4062.                 CloseInfoWindow();
  4063.             else
  4064.                 OpenInfoWindow();
  4065.  
  4066.             break;
  4067.  
  4068.         case MEN_REVIEW_WINDOW:
  4069.  
  4070.             if(ReviewWindow)
  4071.                 DeleteReview();
  4072.             else
  4073.                 CreateReview();
  4074.  
  4075.             break;
  4076.  
  4077.         case MEN_MATRIX_WINDOW:
  4078.  
  4079.             if(MatrixWindow)
  4080.                 CloseMatrixWindow();
  4081.             else
  4082.                 OpenMatrixWindow(Window);
  4083.  
  4084.             break;
  4085.  
  4086.             /* Open the packet window if necessary, else
  4087.              * just activate it.
  4088.              */
  4089.  
  4090.         case MEN_PACKET_WINDOW:
  4091.  
  4092.             CreatePacketWindow();
  4093.             break;
  4094.  
  4095.             // Enable or disable the packet window
  4096.  
  4097.         case MEN_CHAT_LINE:
  4098.  
  4099.             if(Item = FindThisItem(Menu,MEN_CHAT_LINE))
  4100.             {
  4101.                 BOOL NewState;
  4102.  
  4103.                 if(Item -> Flags & CHECKED)
  4104.                     NewState = TRUE;
  4105.                 else
  4106.                     NewState = FALSE;
  4107.  
  4108.                 if(ChatMode != NewState)
  4109.                 {
  4110.                     ChatMode = NewState;
  4111.  
  4112.                     ResetDisplay = TRUE;
  4113.                 }
  4114.             }
  4115.  
  4116.             break;
  4117.  
  4118.             /* Toggle the presence of the fast! macro panel. */
  4119.  
  4120.         case MEN_FAST_MACROS_WINDOW:
  4121.  
  4122.             if(FastWindow)
  4123.                 CloseFastWindow();
  4124.             else
  4125.                 OpenFastWindow();
  4126.  
  4127.             break;
  4128.  
  4129.             /* Open the upload queue window. */
  4130.  
  4131.         case MEN_UPLOAD_QUEUE_WINDOW:
  4132.  
  4133.             CreateQueueProcess();
  4134.             break;
  4135.  
  4136.         default:if(Code >= DIAL_MENU_LIMIT)
  4137.             {
  4138.                 LONG Index = Code - DIAL_MENU_LIMIT;
  4139.  
  4140.                 ObtainSemaphore(&OnlineSemaphore);
  4141.  
  4142.                 if(!LocalDialList && (!Online || Config -> MiscConfig -> ProtectiveMode))
  4143.                 {
  4144.                     ReleaseSemaphore(&OnlineSemaphore);
  4145.  
  4146.                     if(LocalDialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
  4147.                     {
  4148.                         LONG i;
  4149.  
  4150.                             /* Clear previous list contents, we
  4151.                              * don't want to redial yet.
  4152.                              */
  4153.  
  4154.                         for(i = 0 ; i < NumPhoneEntries ; i++)
  4155.                             Phonebook[i] -> Count = -1;
  4156.  
  4157.                         NewList(LocalDialList);
  4158.                     }
  4159.                 }
  4160.                 else
  4161.                     ReleaseSemaphore(&OnlineSemaphore);
  4162.  
  4163.                 if(Phonebook[Index] -> Count == -1)
  4164.                 {
  4165.                     if(LocalDialList)
  4166.                     {
  4167.                         struct PhoneNode *NewNode;
  4168.  
  4169.                             /* Create a new node to be added to the dial list. */
  4170.  
  4171.                         if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
  4172.                         {
  4173.                                 /* Take care of the name and the corresponding phone book entry. */
  4174.  
  4175.                             NewNode -> VanillaNode . ln_Name    = NewNode -> LocalName;
  4176.                             NewNode -> Entry            = Phonebook[Index];
  4177.  
  4178.                             Phonebook[Index] -> Count = ++LocalCount;
  4179.  
  4180.                             SPrintf(NewNode -> LocalName,"%3ld - %s",LocalCount + 1,Phonebook[Index] -> Header -> Name);
  4181.  
  4182.                                 /* Install back-link. */
  4183.  
  4184.                             NewNode -> Entry -> Node = NewNode;
  4185.  
  4186.                             AddTail(LocalDialList,&NewNode -> VanillaNode);
  4187.                         }
  4188.                     }
  4189.                 }
  4190.             }
  4191.  
  4192.             break;
  4193.     }
  4194. }
  4195.  
  4196.     /* HandleMenu(ULONG Code,ULONG Qualifier):
  4197.      *
  4198.      *    Skip along the number of selected menu items and
  4199.      *    handle the associated functions.
  4200.      */
  4201.  
  4202. VOID __regargs
  4203. HandleMenu(ULONG Code,ULONG Qualifier)
  4204. {
  4205.     struct MenuItem *MenuItem;
  4206.  
  4207.     DisplayReopened = FALSE;
  4208.  
  4209.         /* Check until the last menuitem has been
  4210.          * processed.
  4211.          */
  4212.  
  4213.     while(Code != MENUNULL)
  4214.     {
  4215.             /* Pick up the associated menu item. */
  4216.  
  4217.         if(MenuItem = ItemAddress(Menu,Code))
  4218.         {
  4219.             HandleMenuCode((ULONG)GTMENUITEM_USERDATA(MenuItem),Qualifier);
  4220.  
  4221.             if(Apocalypse)
  4222.                 return;
  4223.  
  4224.             if(DisplayReopened)
  4225.             {
  4226.                 DisplayReopened = FALSE;
  4227.  
  4228.                 return;
  4229.             }
  4230.  
  4231.             Code = MenuItem -> NextSelect;
  4232.         }
  4233.         else
  4234.             break;
  4235.     }
  4236.  
  4237.         /* If the modem is still online, provide help. */
  4238.  
  4239.     if(LocalDialList)
  4240.     {
  4241.         if(!AskDial(Window))
  4242.         {
  4243.             FreeList(LocalDialList);
  4244.  
  4245.             FreeVecPooled(LocalDialList);
  4246.  
  4247.             LocalDialList = NULL;
  4248.  
  4249.             LocalCount = -1;
  4250.         }
  4251.     }
  4252.  
  4253.     HandleLocalDialList(FALSE);
  4254. }
  4255.  
  4256.     /* HandleWorkbenchWindow():
  4257.      *
  4258.      *    Handle input coming from the Workbench window.
  4259.      */
  4260.  
  4261. BYTE
  4262. HandleWorkbenchWindow()
  4263. {
  4264.     struct FileInfoBlock    *FileInfo;
  4265.     struct AppMessage    *AppMessage;
  4266.  
  4267.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  4268.     {
  4269.         struct FileTransferInfo *Info;
  4270.  
  4271.         if(Info = AllocFileTransferInfo())
  4272.         {
  4273.             LONG FilesFound = 0,i;
  4274.             BYTE Success = TRUE;
  4275.  
  4276.             while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4277.             {
  4278.                 if(Success && AppMessage -> am_Type == MTYPE_APPWINDOW)
  4279.                 {
  4280.                     for(i = 0 ; Success && i < AppMessage -> am_NumArgs ; i++)
  4281.                     {
  4282.                         if(AppMessage -> am_ArgList[i] . wa_Lock && AppMessage -> am_ArgList[i] . wa_Name)
  4283.                         {
  4284.                             BPTR OldLock;
  4285.  
  4286.                             if(OldLock = CurrentDir(AppMessage -> am_ArgList[i] . wa_Lock))
  4287.                             {
  4288.                                 BPTR FileLock;
  4289.  
  4290.                                 if(FileLock = Lock(AppMessage -> am_ArgList[i] . wa_Name,ACCESS_READ))
  4291.                                 {
  4292.                                     if(Examine(FileLock,FileInfo))
  4293.                                     {
  4294.                                         if(FileInfo -> fib_DirEntryType < 0)
  4295.                                         {
  4296.                                             if(NameFromLock(FileLock,SharedBuffer,512))
  4297.                                             {
  4298.                                                 if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4299.                                                     Success = FALSE;
  4300.                                                 else
  4301.                                                 {
  4302.                                                     FilesFound++;
  4303.  
  4304.                                                     if(Config -> TransferConfig -> TransferIcons)
  4305.                                                     {
  4306.                                                         BPTR InfoLock;
  4307.  
  4308.                                                         strcat(SharedBuffer,".info");
  4309.  
  4310.                                                         if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  4311.                                                         {
  4312.                                                             if(Examine(InfoLock,FileInfo))
  4313.                                                             {
  4314.                                                                 if(FileInfo -> fib_DirEntryType < 0)
  4315.                                                                 {
  4316.                                                                     if(!AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  4317.                                                                         Success = FALSE;
  4318.                                                                     else
  4319.                                                                         FilesFound++;
  4320.                                                                 }
  4321.                                                             }
  4322.  
  4323.                                                             UnLock(InfoLock);
  4324.                                                         }
  4325.                                                     }
  4326.                                                 }
  4327.                                             }
  4328.                                         }
  4329.                                     }
  4330.  
  4331.                                     UnLock(FileLock);
  4332.                                 }
  4333.  
  4334.                                 CurrentDir(OldLock);
  4335.                             }
  4336.                         }
  4337.                     }
  4338.                 }
  4339.  
  4340.                 ReplyMsg((struct Message *)AppMessage);
  4341.             }
  4342.  
  4343.             if(FilesFound)
  4344.             {
  4345.                 SortFileTransferInfo(Info);
  4346.  
  4347.                 BlockWindows();
  4348.  
  4349.                 switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_TRANSFER_FILES_AS_TXT),LocaleString(MSG_TERMMAIN_BINARY_UPLOAD_CANCEL_TXT)))
  4350.                 {
  4351.                     case 1:    BinaryTransfer        = TRUE;
  4352.                         FileTransferInfo    = Info;
  4353.  
  4354.                         StartXprSendFromList(TRANSFER_BINARY,TRUE);
  4355.  
  4356.                         break;
  4357.  
  4358.                     case 2:    BinaryTransfer        = FALSE;
  4359.                         FileTransferInfo    = Info;
  4360.  
  4361.                         StartXprSendFromList(TRANSFER_TEXT,TRUE);
  4362.  
  4363.                         break;
  4364.  
  4365.                     case 0:    FreeFileTransferInfo(Info);
  4366.                         break;
  4367.                 }
  4368.  
  4369.                 ReleaseWindows();
  4370.             }
  4371.         }
  4372.  
  4373.         FreeDosObject(DOS_FIB,FileInfo);
  4374.     }
  4375.  
  4376.     while(AppMessage = (struct AppMessage *)GetMsg(WorkbenchPort))
  4377.         ReplyMsg((struct Message *)AppMessage);
  4378.  
  4379.     return(FALSE);
  4380. }
  4381.  
  4382.     /* HandleIconify():
  4383.      *
  4384.      *    Handle program iconification.
  4385.      */
  4386.  
  4387. VOID
  4388. HandleIconify()
  4389. {
  4390.     BYTE Released = FALSE;
  4391.  
  4392.         /* Set the wait mouse pointer... */
  4393.  
  4394.     BlockWindows();
  4395.  
  4396.         /* Open workbench.library. */
  4397.  
  4398.     if(WorkbenchBase)
  4399.     {
  4400.             /* Open icon.library. */
  4401.  
  4402.         if(IconBase)
  4403.         {
  4404.             struct DiskObject    *Icon = NULL;
  4405.             UBYTE             LocalBuffer[MAX_FILENAME_LENGTH];
  4406.  
  4407.             strcpy(LocalBuffer,Config -> PathConfig -> DefaultStorage);
  4408.  
  4409.             if(AddPart(LocalBuffer,"term_SleepIcon",MAX_FILENAME_LENGTH))
  4410.                 Icon = GetDiskObject(LocalBuffer);
  4411.  
  4412.             if(!Icon)
  4413.                 Icon = GetDiskObject("PROGDIR:term_SleepIcon");
  4414.  
  4415.             if(!Icon)
  4416.             {
  4417.                 if(!(Icon = GetProgramIcon()))
  4418.                     Icon = GetDefDiskObject(WBTOOL);
  4419.             }
  4420.  
  4421.                 /* Did we get an icon? */
  4422.  
  4423.             if(Icon)
  4424.             {
  4425.                 struct MsgPort *IconPort;
  4426.  
  4427.                     /* Reset the icon type. */
  4428.  
  4429.                 Icon -> do_Type        = NULL;
  4430.  
  4431.                     /* Default icon position. */
  4432.  
  4433.                 Icon -> do_CurrentX    = NO_ICON_POSITION;
  4434.                 Icon -> do_CurrentY    = NO_ICON_POSITION;
  4435.  
  4436.                     /* Create the Workbench reply port. */
  4437.  
  4438.                 if(IconPort = CreateMsgPort())
  4439.                 {
  4440.                     struct AppIcon *AppIcon;
  4441.  
  4442.                         /* Add the application icon. */
  4443.  
  4444.                     if(AppIcon = AddAppIconA(0,0,TermIDString,IconPort,NULL,Icon,NULL))
  4445.                     {
  4446.                         struct AppMessage    *AppMessage;
  4447.                         UBYTE            *String,*Error;
  4448.                         ULONG             SignalSet;
  4449.  
  4450.                             /* Reset the guardian. */
  4451.  
  4452.                         IconTerminated = FALSE;
  4453.  
  4454.                             /* Release the window. */
  4455.  
  4456.                         Released = TRUE;
  4457.  
  4458.                         ReleaseWindows();
  4459.  
  4460.                         WindowBox . Left    = Window -> LeftEdge;
  4461.                         WindowBox . Top        = Window -> TopEdge;
  4462.                         WindowBox . Width    = Window -> Width;
  4463.                         WindowBox . Height    = Window -> Height;
  4464.  
  4465.                             /* Close the display. full stop. */
  4466.  
  4467.                         if(DeleteDisplay())
  4468.                         {
  4469.                                 /* Reset and release the serial driver. */
  4470.  
  4471.                             if(Config -> MiscConfig -> ReleaseDevice)
  4472.                             {
  4473.                                 ClearSerial();
  4474.  
  4475.                                 DeleteSerial();
  4476.                             }
  4477.  
  4478.                                 /* Wait for double-click. */
  4479.  
  4480. IconLoop:                        while(!IconTerminated)
  4481.                             {
  4482.                                 SignalSet = Wait(PORTMASK(IconPort) | SIG_REXX | SIGBREAKF_CTRL_F);
  4483.  
  4484.                                 if(SignalSet & PORTMASK(IconPort))
  4485.                                 {
  4486.                                         /* Pick up application messages. */
  4487.  
  4488.                                     while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4489.                                     {
  4490.                                             /* Received a double-click? */
  4491.  
  4492.                                         IconTerminated = TRUE;
  4493.  
  4494.                                         ReplyMsg(AppMessage);
  4495.                                     }
  4496.                                 }
  4497.  
  4498.                                     /* Wake up if ARexx command received. */
  4499.  
  4500.                                 if(SignalSet & SIG_REXX)
  4501.                                     while(HandleRexx());
  4502.  
  4503.                                 if(SignalSet & SIGBREAKF_CTRL_F)
  4504.                                     IconTerminated = TRUE;
  4505.                             }
  4506.  
  4507.                                 /* Open the serial driver. */
  4508.  
  4509.                             if(Config -> MiscConfig -> ReleaseDevice)
  4510.                             {
  4511.                                 if(Error = CreateSerial())
  4512.                                 {
  4513.                                     DeleteSerial();
  4514.  
  4515.                                     switch(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_IGNORE_QUIT_TXT),Error))
  4516.                                     {
  4517.                                         case 1:    IconTerminated = FALSE;
  4518.                                             goto IconLoop;
  4519.  
  4520.                                         case 0:    MainTerminated = TRUE;
  4521.                                     }
  4522.                                 }
  4523.                                 else
  4524.                                 {
  4525.                                     if(SerialMessage)
  4526.                                     {
  4527.                                         MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),SerialMessage);
  4528.  
  4529.                                         SerialMessage = NULL;
  4530.                                     }
  4531.                                 }
  4532.                             }
  4533.  
  4534.                             if(CantQuit && MainTerminated)
  4535.                                 MainTerminated = FALSE;
  4536.  
  4537.                                 /* Create the display. */
  4538.  
  4539.                             if(!MainTerminated)
  4540.                             {
  4541.                                 if(String = CreateDisplay(FALSE))
  4542.                                 {
  4543.                                     if(MyEasyRequest(NULL,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_TERMMAIN_ICONIFY_QUIT_TXT),String))
  4544.                                     {
  4545.                                         ClearSerial();
  4546.  
  4547.                                         DeleteSerial();
  4548.  
  4549.                                         IconTerminated = FALSE;
  4550.  
  4551.                                         goto IconLoop;
  4552.                                     }
  4553.                                     else
  4554.                                         MainTerminated = TRUE;
  4555.                                 }
  4556.                                 else
  4557.                                 {
  4558.                                     BumpWindow(Window);
  4559.  
  4560.                                     PubScreenStuff();
  4561.                                 }
  4562.                             }
  4563.                         }
  4564.                         else
  4565.                         {
  4566.                             BlockWindows();
  4567.  
  4568.                             MyEasyRequest(Window,LocaleString(MSG_GLOBAL_TERM_HAS_A_PROBLEM_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),LocaleString(MSG_TERMMAIN_CANNOT_CLOSE_SCREEN_YET_TXT));
  4569.  
  4570.                             ReleaseWindows();
  4571.                         }
  4572.  
  4573.                             /* Remove the application icon. */
  4574.  
  4575.                         RemoveAppIcon(AppIcon);
  4576.  
  4577.                             /* Reply pending messages. */
  4578.  
  4579.                         while(AppMessage = (struct AppMessage *)GetMsg(IconPort))
  4580.                             ReplyMsg(AppMessage);
  4581.                     }
  4582.                     else
  4583.                         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_ADD_APPLICATION_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4584.  
  4585.                     DeleteMsgPort(IconPort);
  4586.                 }
  4587.                 else
  4588.                     MyEasyRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_CREATE_MSGPORT_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4589.  
  4590.                 FreeDiskObject(Icon);
  4591.             }
  4592.             else
  4593.                 MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_TOOL_ICON_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4594.         }
  4595.         else
  4596.             MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_ICON_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4597.     }
  4598.     else
  4599.         MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_FAILED_TO_OPEN_WORKBENCH_LIBRARY_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  4600.  
  4601.     if(!Released)
  4602.         ReleaseWindows();
  4603.  
  4604.         /* Finished! */
  4605.  
  4606.     DoIconify = FALSE;
  4607. }
  4608.  
  4609.     /* HandleOnlineCleanup():
  4610.      *
  4611.      *    Perform offline cleanup tasks.
  4612.      */
  4613.  
  4614. VOID __regargs
  4615. HandleOnlineCleanup(BOOL Hangup)
  4616. {
  4617.     SoundPlay(SOUND_DISCONNECT);
  4618.  
  4619.         /* Execute logoff macro. */
  4620.  
  4621.     if(Config -> CommandConfig -> LogoffMacro[0] && WasOnline)
  4622.         SerialCommand(Config -> CommandConfig -> LogoffMacro);
  4623.  
  4624.     StopCall(FALSE);
  4625.  
  4626.     if(CurrentPay)
  4627.     {
  4628.         if(Hangup)
  4629.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_COST_TXT),CreateSum(CurrentPay,TRUE));
  4630.         else
  4631.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_COST_TXT),CreateSum(CurrentPay,TRUE));
  4632.     }
  4633.     else
  4634.     {
  4635.         if(Hangup)
  4636.             LogAction(LocaleString(MSG_TERMMAIN_LOGMSG_HANG_UP_TXT));
  4637.         else
  4638.             LogAction(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4639.     }
  4640.  
  4641.     SetDialMenu(TRUE);
  4642.  
  4643.     if(!Hangup)
  4644.         Say(LocaleString(MSG_TERMAUX_CARRIER_LOST_TXT));
  4645.  
  4646.         /* Clear the password. */
  4647.  
  4648.     Password[0]        = 0;
  4649.     UserName[0]        = 0;
  4650.  
  4651.     CurrentBBSName[0]    = 0;
  4652.     CurrentBBSComment[0]    = 0;
  4653.     CurrentBBSNumber[0]    = 0;
  4654.  
  4655.     ObtainSemaphore(&OnlineSemaphore);
  4656.  
  4657.     if(!Config -> SerialConfig -> CheckCarrier || Config -> SerialConfig -> DirectConnection)
  4658.         Online = WasOnline = FALSE;
  4659.  
  4660.     ReleaseSemaphore(&OnlineSemaphore);
  4661.  
  4662.     ObtainSemaphore(&PatternSemaphore);
  4663.  
  4664.     ChosenEntry    = NULL;
  4665.     ChosenPattern    = NULL;
  4666.  
  4667.     ReleaseSemaphore(&PatternSemaphore);
  4668.  
  4669.     LimitCount = -1;
  4670.  
  4671.         /* Previous configuration available? */
  4672.  
  4673.     if(BackupConfig)
  4674.     {
  4675.             /* Remember old configuration. */
  4676.  
  4677.         SaveConfig(Config,PrivateConfig);
  4678.  
  4679.             /* Copy configuration. */
  4680.  
  4681.         SaveConfig(BackupConfig,Config);
  4682.  
  4683.             /* Set up new configuration. */
  4684.  
  4685.         ConfigSetup();
  4686.  
  4687.             /* Free old configuration. */
  4688.  
  4689.         DeleteConfiguration(BackupConfig);
  4690.  
  4691.         BackupConfig = NULL;
  4692.     }
  4693.  
  4694.     if(!ResetDisplay && CurrentPay)
  4695.     {
  4696.             /* Reset the text rendering styles, font, etc. in
  4697.              * order to keep the following text from getting
  4698.              * illegible.
  4699.              */
  4700.  
  4701.         SoftReset();
  4702.  
  4703.             /* Display how much we expect
  4704.              * the user will have to pay for
  4705.              * this call.
  4706.              */
  4707.  
  4708.         ConWrites(LocaleString(MSG_TERMMAIN_THIS_CALL_WILL_COST_YOU_TXT),CreateSum(CurrentPay,TRUE));
  4709.  
  4710.         CurrentPay = 0;
  4711.     }
  4712.  
  4713.     if(Config -> ModemConfig -> RedialAfterHangup || KeepRedialing)
  4714.     {
  4715.         if(DialList)
  4716.         {
  4717.             if(DialList -> lh_Head -> ln_Succ)
  4718.             {
  4719.                 ObtainSemaphore(&OnlineSemaphore);
  4720.  
  4721.                 Online = WasOnline = FALSE;
  4722.  
  4723.                 ReleaseSemaphore(&OnlineSemaphore);
  4724.  
  4725.                 DoDial = DIAL_REDIAL;
  4726.             }
  4727.             else
  4728.             {
  4729.                 if(KeepRedialing)
  4730.                 {
  4731.                     KeepRedialing = FALSE;
  4732.  
  4733.                     if(PhonebookAutoExit)
  4734.                         MainTerminated = TRUE;
  4735.                 }
  4736.             }
  4737.         }
  4738.         else
  4739.             KeepRedialing = FALSE;
  4740.     }
  4741. }
  4742.  
  4743.     /* HandleFlowChange():
  4744.      *
  4745.      *    Handle data flow scanner information.
  4746.      */
  4747.  
  4748. VOID
  4749. HandleFlowChange()
  4750. {
  4751.     ObtainSemaphore(&OnlineSemaphore);
  4752.  
  4753.     if(Online)
  4754.     {
  4755.         if(FlowInfo . NoCarrier)
  4756.         {
  4757.             if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  4758.             {
  4759.                     /* Is the carrier still present? */
  4760.  
  4761.                 if(!(GetSerialStatus() & CIAF_COMCD))    // = Carrier detected
  4762.                     FlowInfo . NoCarrier = FALSE;
  4763.             }
  4764.  
  4765.             if(FlowInfo . NoCarrier)
  4766.             {
  4767.                 if(Online)
  4768.                 {
  4769.                     WasOnline    = Online;
  4770.                     Online        = FALSE;
  4771.                 }
  4772.             }
  4773.         }
  4774.  
  4775.         ReleaseSemaphore(&OnlineSemaphore);
  4776.     }
  4777.     else
  4778.     {
  4779.         ReleaseSemaphore(&OnlineSemaphore);
  4780.  
  4781.         if(FlowInfo . Voice)
  4782.         {
  4783.             UBYTE DateTimeBuffer[256];
  4784.  
  4785.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4786.  
  4787.             WakeUp(Window,SOUND_VOICE);
  4788.  
  4789.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_VOIC_CALL_TXT),DateTimeBuffer);
  4790.  
  4791.             Say(LocaleString(MSG_TERMMAIN_SAY_INCOMING_VOICE_CALL_TXT));
  4792.         }
  4793.  
  4794.         if(FlowInfo . Ring)
  4795.         {
  4796.             UBYTE DateTimeBuffer[256];
  4797.  
  4798.             FormatStamp(NULL,NULL,NULL,DateTimeBuffer,FALSE);
  4799.  
  4800.             WakeUp(Window,SOUND_RING);
  4801.  
  4802.             ConWrites(LocaleString(MSG_TERMMAIN_INCOMING_CALL_TXT),DateTimeBuffer);
  4803.  
  4804.             Say(LocaleString(MSG_GLOBAL_INCOMING_CALL_TXT));
  4805.         }
  4806.  
  4807.         if(FlowInfo . Connect)
  4808.         {
  4809.                 /* Are we to check the carrier signal? */
  4810.  
  4811.             if(Config -> SerialConfig -> CheckCarrier && !Config -> SerialConfig -> DirectConnection)
  4812.             {
  4813.                     /* No carrier signal present? */
  4814.  
  4815.                 if(GetSerialStatus() & CIAF_COMCD)    // = Carrier lost
  4816.                     FlowInfo . Connect = FALSE;
  4817.             }
  4818.  
  4819.             if(FlowInfo . Connect)
  4820.             {
  4821.                 WakeUp(Window,SOUND_CONNECT);
  4822.  
  4823.                 ObtainSemaphore(&OnlineSemaphore);
  4824.  
  4825.                 if(!Online)
  4826.                 {
  4827.                     WasOnline    = Online;
  4828.                     Online        = TRUE;
  4829.                 }
  4830.  
  4831.                 BaudPending = FALSE;
  4832.  
  4833.                 ReleaseSemaphore(&OnlineSemaphore);
  4834.  
  4835.                 SetDialMenu(FALSE);
  4836.             }
  4837.         }
  4838.     }
  4839.  
  4840.         /* Check if we are to prompt the user for
  4841.          * file transfer.
  4842.          */
  4843.  
  4844.     if(FlowInfo . Signature)
  4845.     {
  4846.         WORD Type = FlowInfo . Signature - SCAN_SIGDEFAULTUPLOAD + TRANSFERSIG_DEFAULTUPLOAD;
  4847.  
  4848.         switch(Type)
  4849.         {
  4850.             case TRANSFERSIG_DEFAULTUPLOAD:
  4851.  
  4852.                 BlockWindows();
  4853.  
  4854.                 switch(UploadPanel(TRUE))
  4855.                 {
  4856.                     case UPLOAD_TEXT:
  4857.  
  4858.                         BinaryTransfer = FALSE;
  4859.  
  4860.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  4861.                             SerWrite(ZModemCancel,20);
  4862.  
  4863.                         break;
  4864.  
  4865.                     case UPLOAD_BINARY:
  4866.  
  4867.                         BinaryTransfer = TRUE;
  4868.  
  4869.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  4870.                             SerWrite(ZModemCancel,20);
  4871.  
  4872.                         break;
  4873.  
  4874.                     case UPLOAD_ABORT:
  4875.  
  4876.                         SerWrite(ZModemCancel,20);
  4877.                         break;
  4878.  
  4879.                     case UPLOAD_BINARY_FROM_LIST:
  4880.  
  4881.                         StartUpload(UPLOAD_BINARY);
  4882.                         break;
  4883.  
  4884.                     case UPLOAD_TEXT_FROM_LIST:
  4885.  
  4886.                         StartUpload(UPLOAD_TEXT);
  4887.                         break;
  4888.                 }
  4889.  
  4890.                 ReleaseWindows();
  4891.  
  4892.                 break;
  4893.  
  4894.             case TRANSFERSIG_DEFAULTDOWNLOAD:
  4895.  
  4896.                 BlockWindows();
  4897.  
  4898.                 switch(UploadPanel(FALSE))
  4899.                 {
  4900.                     case UPLOAD_TEXT:
  4901.  
  4902.                         BinaryTransfer = FALSE;
  4903.  
  4904.                         StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4905.  
  4906.                         BinaryTransfer = TRUE;
  4907.  
  4908.                         break;
  4909.  
  4910.                     case UPLOAD_BINARY:
  4911.  
  4912.                         BinaryTransfer = TRUE;
  4913.  
  4914.                         StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  4915.  
  4916.                         break;
  4917.                 }
  4918.  
  4919.                 ReleaseWindows();
  4920.  
  4921.                 break;
  4922.  
  4923.             case TRANSFERSIG_ASCIIUPLOAD:
  4924.  
  4925.                 BlockWindows();
  4926.  
  4927.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIUploadLibrary,Config -> TransferConfig -> ASCIIUploadType))
  4928.                 {
  4929.                     BinaryTransfer = FALSE;
  4930.  
  4931.                     StartXprSend(TRANSFER_ASCII,TRUE);
  4932.  
  4933.                     BinaryTransfer = TRUE;
  4934.                 }
  4935.  
  4936.                 ResetProtocol();
  4937.  
  4938.                 ReleaseWindows();
  4939.  
  4940.                 break;
  4941.  
  4942.             case TRANSFERSIG_ASCIIDOWNLOAD:
  4943.  
  4944.                 BlockWindows();
  4945.  
  4946.                 if(ChangeProtocol(Config -> TransferConfig -> ASCIIDownloadLibrary,Config -> TransferConfig -> ASCIIDownloadType))
  4947.                 {
  4948.                     BinaryTransfer = FALSE;
  4949.  
  4950.                     StartXprReceive(TRANSFER_ASCII,NULL,TRUE);
  4951.  
  4952.                     BinaryTransfer = TRUE;
  4953.                 }
  4954.  
  4955.                 ResetProtocol();
  4956.  
  4957.                 ReleaseWindows();
  4958.  
  4959.                 break;
  4960.  
  4961.             case TRANSFERSIG_TEXTUPLOAD:
  4962.  
  4963.                 BlockWindows();
  4964.  
  4965.                 if(ChangeProtocol(Config -> TransferConfig -> TextUploadLibrary,Config -> TransferConfig -> TextUploadType))
  4966.                 {
  4967.                     BinaryTransfer = FALSE;
  4968.  
  4969.                     StartXprSend(TRANSFER_TEXT,TRUE);
  4970.  
  4971.                     BinaryTransfer = TRUE;
  4972.                 }
  4973.  
  4974.                 ResetProtocol();
  4975.  
  4976.                 ReleaseWindows();
  4977.  
  4978.                 break;
  4979.  
  4980.             case TRANSFERSIG_TEXTDOWNLOAD:
  4981.  
  4982.                 BlockWindows();
  4983.  
  4984.                 if(ChangeProtocol(Config -> TransferConfig -> TextDownloadLibrary,Config -> TransferConfig -> TextDownloadType))
  4985.                 {
  4986.                     BinaryTransfer = FALSE;
  4987.  
  4988.                     StartXprReceive(TRANSFER_TEXT,NULL,TRUE);
  4989.  
  4990.                     BinaryTransfer = TRUE;
  4991.                 }
  4992.  
  4993.                 ResetProtocol();
  4994.  
  4995.                 ReleaseWindows();
  4996.  
  4997.                 break;
  4998.  
  4999.  
  5000.             case TRANSFERSIG_BINARYUPLOAD:
  5001.  
  5002.                 BlockWindows();
  5003.  
  5004.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryUploadLibrary,Config -> TransferConfig -> BinaryUploadType))
  5005.                 {
  5006.                     BinaryTransfer = TRUE;
  5007.  
  5008.                     StartXprSend(TRANSFER_BINARY,TRUE);
  5009.                 }
  5010.  
  5011.                 ResetProtocol();
  5012.  
  5013.                 ReleaseWindows();
  5014.  
  5015.                 break;
  5016.  
  5017.             case TRANSFERSIG_BINARYDOWNLOAD:
  5018.  
  5019.                 BlockWindows();
  5020.  
  5021.                 if(ChangeProtocol(Config -> TransferConfig -> BinaryDownloadLibrary,Config -> TransferConfig -> BinaryDownloadType))
  5022.                 {
  5023.                     BinaryTransfer = TRUE;
  5024.  
  5025.                     StartXprReceive(TRANSFER_BINARY,NULL,TRUE);
  5026.                 }
  5027.  
  5028.                 ResetProtocol();
  5029.  
  5030.                 ReleaseWindows();
  5031.  
  5032.                 break;
  5033.         }
  5034.     }
  5035.  
  5036.     FlowInit(TRUE);
  5037. }
  5038.  
  5039.     /* HandleSerialReset():
  5040.      *
  5041.      *    Handle serial device reset.
  5042.      */
  5043.  
  5044. VOID
  5045. HandleSerialReset()
  5046. {
  5047.     ClearSerial();
  5048.  
  5049.     DeleteSerial();
  5050.  
  5051.     BlockWindows();
  5052.  
  5053.     ReopenSerial();
  5054.  
  5055.     ReleaseWindows();
  5056. }
  5057.  
  5058.     /* HandleSerialRelease():
  5059.      *
  5060.      *    Release the serial device driver, then reopen it again.
  5061.      */
  5062.  
  5063. VOID
  5064. HandleSerialRelease()
  5065. {
  5066.     APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  5067.     BYTE    Continue,SerialClosed;
  5068.  
  5069.     ThisProcess -> pr_WindowPtr = (APTR)Window;
  5070.  
  5071.         /* This might happen if an ARexx user
  5072.          * released the serial device and
  5073.          * failed to reopen it.
  5074.          */
  5075.  
  5076.     if(ReadPort)
  5077.         SerialClosed = FALSE;
  5078.     else
  5079.         SerialClosed = TRUE;
  5080.  
  5081.     BlockWindows();
  5082.  
  5083.         /* Prevent catastrophes! */
  5084.  
  5085.     if(!Config -> MiscConfig -> ProtectiveMode)
  5086.         Continue = TRUE;
  5087.     else
  5088.     {
  5089.         ObtainSemaphore(&OnlineSemaphore);
  5090.  
  5091.         if(Online && !SerialClosed)
  5092.         {
  5093.             ReleaseSemaphore(&OnlineSemaphore);
  5094.  
  5095.             if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  5096.                 Continue = FALSE;
  5097.             else
  5098.                 Continue = TRUE;
  5099.         }
  5100.         else
  5101.         {
  5102.             ReleaseSemaphore(&OnlineSemaphore);
  5103.  
  5104.             Continue = TRUE;
  5105.         }
  5106.     }
  5107.  
  5108.     if(Continue)
  5109.     {
  5110.         if(SerialClosed)
  5111.             ReopenSerial();
  5112.         else
  5113.         {
  5114.             ClearSerial();
  5115.  
  5116.             DeleteSerial();
  5117.  
  5118.             switch(MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_UNIT_RESET_AND_RELEASED_TXT),LocaleString(MSG_TERMMAIN_RETURN_QUIT_TXT),Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber))
  5119.             {
  5120.                 case 0:    MainTerminated = TRUE;
  5121.                     break;
  5122.  
  5123.                 case 1:    ReopenSerial();
  5124.                     break;
  5125.  
  5126.                 case 2:    DoIconify = TRUE;
  5127.                     break;
  5128.             }
  5129.         }
  5130.     }
  5131.  
  5132.     ReleaseSerial = FALSE;
  5133.  
  5134.     ThisProcess -> pr_WindowPtr = OldPtr;
  5135.  
  5136.     ReleaseWindows();
  5137. }
  5138.  
  5139.     /* HandleExternalEmulation():
  5140.      *
  5141.      *    Handle external emulation event.
  5142.      */
  5143.  
  5144. VOID
  5145. HandleExternalEmulation()
  5146. {
  5147.     if(!XEmulatorSignal(XEM_IO,XEM_Signal))
  5148.     {
  5149.         CloseEmulator();
  5150.  
  5151.         ResetDisplay = TRUE;
  5152.     }
  5153. }
  5154.  
  5155.     /* HandleSerialCheck():
  5156.      *
  5157.      *    Handle routine checkup actions.
  5158.      */
  5159.  
  5160. BYTE
  5161. HandleSerialCheck()
  5162. {
  5163.         // Attempt to lock the serial device?
  5164.  
  5165.     if(PollODU)
  5166.     {
  5167.             // We don't want to poll too often
  5168.  
  5169.         if(PollODUCount++ == 4)
  5170.         {
  5171.             PollODUCount = 0;
  5172.  
  5173.                 // Still supporting the locking protocol?
  5174.  
  5175.             if(Config -> SerialConfig -> UseOwnDevUnit)
  5176.             {
  5177.                     // Allocate the signal
  5178.  
  5179.                 if((OwnDevBit = AllocSignal(-1)) != -1)
  5180.                 {
  5181.                         // Give it a try
  5182.  
  5183.                     if(!AttemptDevUnit(Config -> SerialConfig -> SerialDevice,Config -> SerialConfig -> UnitNumber,TermIDString,OwnDevBit))
  5184.                     {
  5185.                             // Check
  5186.  
  5187.                         ReopenSerial();
  5188.  
  5189.                         PollODU = FALSE;
  5190.                     }
  5191.                     else
  5192.                     {
  5193.                             // No success
  5194.  
  5195.                         FreeSignal(OwnDevBit);
  5196.  
  5197.                         OwnDevBit = -1;
  5198.                     }
  5199.                 }
  5200.             }
  5201.             else
  5202.                 PollODU = FALSE;
  5203.         }
  5204.     }
  5205.  
  5206.         /* Take a look at the carrier signal. */
  5207.  
  5208.     if(Config -> SerialConfig -> CheckCarrier && WriteRequest && !Config -> SerialConfig -> DirectConnection)
  5209.     {
  5210.         register UWORD Status = GetSerialStatus();
  5211.  
  5212.         ObtainSemaphore(&OnlineSemaphore);
  5213.  
  5214.             /* Still online? */
  5215.  
  5216.         if(Online)
  5217.         {
  5218.             ReleaseSemaphore(&OnlineSemaphore);
  5219.  
  5220.                 /* Carrier detect signal lost? */
  5221.  
  5222.             if(Status & CIAF_COMCD)    // = Carrier lost
  5223.             {
  5224.                 ObtainSemaphore(&OnlineSemaphore);
  5225.  
  5226.                 if(Online)
  5227.                 {
  5228.                     WasOnline    = Online;
  5229.                     Online        = FALSE;
  5230.                 }
  5231.  
  5232.                 ReleaseSemaphore(&OnlineSemaphore);
  5233.             }
  5234.         }
  5235.         else
  5236.         {
  5237.             ReleaseSemaphore(&OnlineSemaphore);
  5238.  
  5239.                 /* Is the carrier detect signal
  5240.                  * present?
  5241.                  */
  5242.  
  5243.             if(!(Status & CIAF_COMCD))    // = Carrier detected
  5244.             {
  5245.                 ObtainSemaphore(&OnlineSemaphore);
  5246.  
  5247.                 if(!Online)
  5248.                 {
  5249.                     WasOnline    = Online;
  5250.                     Online        = TRUE;
  5251.                 }
  5252.  
  5253.                 ReleaseSemaphore(&OnlineSemaphore);
  5254.  
  5255.                 BaudCount        = 0;
  5256.                 BaudBuffer[0]        = 0;
  5257.                 BaudPending        = FALSE;
  5258.  
  5259.                 CurrentPay        = 0;
  5260.  
  5261.                 ObtainSemaphore(&PatternSemaphore);
  5262.  
  5263.                 ChosenEntry        = NULL;
  5264.                 ChosenPattern        = NULL;
  5265.  
  5266.                 ReleaseSemaphore(&PatternSemaphore);
  5267.  
  5268.                 Password[0]        = 0;
  5269.                 UserName[0]        = 0;
  5270.  
  5271.                 SendStartup        = FALSE;
  5272.  
  5273.                 LimitCount        = -1;
  5274.  
  5275.                 CurrentBBSName[0]    = 0;
  5276.                 CurrentBBSComment[0]    = 0;
  5277.                 CurrentBBSNumber[0]    = 0;
  5278.  
  5279.                 SetDialMenu(FALSE);
  5280.             }
  5281.         }
  5282.     }
  5283.  
  5284.         /* Check online time limit. */
  5285.  
  5286.     if(!LimitCount)
  5287.     {
  5288.         LimitCount = -1;
  5289.  
  5290.         BlockWindows();
  5291.  
  5292.         SendARexxCommand(LimitMacro,TRUE);
  5293.  
  5294.         ReleaseWindows();
  5295.     }
  5296.  
  5297.         /* Flush capture file contents to disk,
  5298.          * this routine is executed each minute
  5299.          * in order to store the captured data.
  5300.          */
  5301.  
  5302.     if(BufferFlushCount-- <= 0)
  5303.     {
  5304.         BufferFlushCount = 60;
  5305.  
  5306.             /* Flush the capture file. */
  5307.  
  5308.         if(FileCapture)
  5309.             BufferFlush(FileCapture);
  5310.     }
  5311.  
  5312.     return(FALSE);
  5313. }
  5314.  
  5315.     /* HandleQueueMsg():
  5316.      *
  5317.      *    Process the special message queue.
  5318.      */
  5319.  
  5320. BYTE
  5321. HandleQueueMsg()
  5322. {
  5323.     struct DataMsg *Item;
  5324.  
  5325.     if(Item = GetMsgItem(SpecialQueue))
  5326.     {
  5327.         struct FileTransferInfo *Info;
  5328.         BYTE             OldEcho;
  5329.  
  5330.         switch(Item -> Type)
  5331.         {
  5332.                 // Output data.
  5333.  
  5334.             case DATAMSGTYPE_WRITE:
  5335.  
  5336.                 SerWrite(Item -> Data,Item -> Size);
  5337.                 break;
  5338.  
  5339.                 // Execute a command.
  5340.  
  5341.             case DATAMSGTYPE_SERIALCOMMAND:
  5342.  
  5343.                 SerialCommand(Item -> Data);
  5344.                 break;
  5345.  
  5346.                 // Execute a command, but don't echo it.
  5347.  
  5348.             case DATAMSGTYPE_SERIALCOMMANDNOECHO:
  5349.  
  5350.                 OldEcho = Config -> SerialConfig -> Duplex;
  5351.  
  5352.                 Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  5353.  
  5354.                 SerialCommand(Item -> Data);
  5355.  
  5356.                 Config -> SerialConfig -> Duplex = OldEcho;
  5357.                 break;
  5358.  
  5359.                 // Output contents of clipboard
  5360.  
  5361.             case DATAMSGTYPE_WRITECLIP:
  5362.  
  5363.                 if(!ClipInput)
  5364.                 {
  5365.                     if(!OpenClip(Item -> Size))
  5366.                         ClipInput = ClipXerox = TRUE;
  5367.                     else
  5368.                         ClipInput = ClipXerox = FALSE;
  5369.                 }
  5370.  
  5371.                     /* Are we reading input from the clipboard? */
  5372.  
  5373.                 if(ClipInput)
  5374.                 {
  5375.                     UBYTE    InputBuffer[257];
  5376.                     WORD    Len;
  5377.  
  5378.                     if((Len = GetClip(InputBuffer,256,TRUE)) < 0)
  5379.                     {
  5380.                         CloseClip();
  5381.  
  5382.                         ClipInput = FALSE;
  5383.  
  5384.                         if(ClipXerox)
  5385.                         {
  5386.                             if(Config -> ClipConfig -> InsertSuffix[0])
  5387.                                 SerialCommand(Config -> ClipConfig -> InsertSuffix);
  5388.  
  5389.                             ClipXerox = FALSE;
  5390.                         }
  5391.  
  5392.                         ClipPrefix = FALSE;
  5393.                     }
  5394.                     else
  5395.                     {
  5396.                         if(!ClipPrefix && ClipXerox)
  5397.                         {
  5398.                             if(Config -> ClipConfig -> InsertPrefix[0])
  5399.                                 SerialCommand(Config -> ClipConfig -> InsertPrefix);
  5400.  
  5401.                             ClipPrefix = TRUE;
  5402.                         }
  5403.  
  5404.                         if(Len > 0)
  5405.                             SendInputTextBuffer(InputBuffer,Len,FALSE,Config -> ClipConfig -> ConvertLF);
  5406.                     }
  5407.                 }
  5408.  
  5409.                 break;
  5410.  
  5411.                 // Start an upload
  5412.  
  5413.             case DATAMSGTYPE_UPLOAD:
  5414.  
  5415.                 if(((struct List *)Item -> Data) -> lh_Head -> ln_Succ)
  5416.                 {
  5417.                     if(Info = AllocFileTransferInfo())
  5418.                     {
  5419.                         struct FileInfoBlock *FileInfo;
  5420.                         LONG FilesFound = 0,Type = Item -> Size;
  5421.  
  5422.                         if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  5423.                         {
  5424.                             BPTR FileLock;
  5425.                             struct List *List;
  5426.                             struct Node *Node,*Next;
  5427.                             APTR OldPtr = ThisProcess -> pr_WindowPtr;
  5428.  
  5429.                             ThisProcess -> pr_WindowPtr = (APTR)-1;
  5430.  
  5431.                             List = (struct List *)Item -> Data;
  5432.  
  5433.                             for(Node = List -> lh_Head ; Next = Node -> ln_Succ ; Node = Next)
  5434.                             {
  5435.                                 if(FileLock = Lock(Node -> ln_Name,ACCESS_READ))
  5436.                                 {
  5437.                                     if(Examine(FileLock,FileInfo))
  5438.                                     {
  5439.                                         if(FileInfo -> fib_DirEntryType < 0)
  5440.                                         {
  5441.                                             if(AddFileTransferNode(Info,Node -> ln_Name,FileInfo -> fib_Size))
  5442.                                                 FilesFound++;
  5443.  
  5444.                                             if(Config -> TransferConfig -> TransferIcons)
  5445.                                             {
  5446.                                                 BPTR InfoLock;
  5447.  
  5448.                                                 strcpy(SharedBuffer,Node -> ln_Name);
  5449.  
  5450.                                                 strcat(SharedBuffer,".info");
  5451.  
  5452.                                                 if(InfoLock = Lock(SharedBuffer,ACCESS_READ))
  5453.                                                 {
  5454.                                                     if(Examine(InfoLock,FileInfo))
  5455.                                                     {
  5456.                                                         if(FileInfo -> fib_DirEntryType < 0)
  5457.                                                         {
  5458.                                                             if(AddFileTransferNode(Info,SharedBuffer,FileInfo -> fib_Size))
  5459.                                                                 FilesFound++;
  5460.                                                         }
  5461.                                                     }
  5462.  
  5463.                                                     UnLock(InfoLock);
  5464.                                                 }
  5465.                                             }
  5466.  
  5467.                                             Remove(Node);
  5468.  
  5469.                                             FreeVecPooled(Node);
  5470.                                         }
  5471.                                     }
  5472.  
  5473.                                     UnLock(FileLock);
  5474.                                 }
  5475.                             }
  5476.  
  5477.                             ThisProcess -> pr_WindowPtr = OldPtr;
  5478.  
  5479.                             FreeDosObject(DOS_FIB,FileInfo);
  5480.                         }
  5481.  
  5482.                         DeleteMsgItem(Item);
  5483.  
  5484.                         Item = NULL;
  5485.  
  5486.                         if(FilesFound)
  5487.                         {
  5488.                             BlockWindows();
  5489.  
  5490.                             SortFileTransferInfo(Info);
  5491.  
  5492.                             switch(Type)
  5493.                             {
  5494.                                 case UPLOAD_BINARY:
  5495.  
  5496.                                     BinaryTransfer        = TRUE;
  5497.                                     FileTransferInfo    = Info;
  5498.  
  5499.                                     StartXprSendFromList(TRANSFER_BINARY,TRUE);
  5500.  
  5501.                                     break;
  5502.  
  5503.                                 case UPLOAD_TEXT:
  5504.  
  5505.                                     BinaryTransfer        = FALSE;
  5506.                                     FileTransferInfo    = Info;
  5507.  
  5508.                                     StartXprSendFromList(TRANSFER_TEXT,TRUE);
  5509.  
  5510.                                     break;
  5511.                             }
  5512.  
  5513.                             ReleaseWindows();
  5514.                         }
  5515.                         else
  5516.                             FreeFileTransferInfo(Info);
  5517.                     }
  5518.                 }
  5519.                 else
  5520.                 {
  5521.                     UBYTE Type = Item -> Size;
  5522.  
  5523.                     DeleteMsgItem(Item);
  5524.  
  5525.                     Item = NULL;
  5526.  
  5527.                     if(Type == UPLOAD_BINARY)
  5528.                     {
  5529.                         BinaryTransfer = TRUE;
  5530.  
  5531.                         if(!StartXprSend(TRANSFER_BINARY,TRUE))
  5532.                             SerWrite(ZModemCancel,20);
  5533.                     }
  5534.                     else
  5535.                     {
  5536.                         BinaryTransfer = FALSE;
  5537.  
  5538.                         if(!StartXprSend(TRANSFER_TEXT,TRUE))
  5539.                             SerWrite(ZModemCancel,20);
  5540.                     }
  5541.                 }
  5542.  
  5543.                 break;
  5544.  
  5545.                 // ARexx script execution finished.
  5546.  
  5547.             case DATAMSGTYPE_COMMANDDONE:
  5548.  
  5549.                 if(CantQuit > 0)
  5550.                     CantQuit--;
  5551.  
  5552.                 BumpWindow(Window);
  5553.  
  5554.                 ReleaseWindows();
  5555.  
  5556.                 ObtainSemaphore(&ARexxQueueSemaphore);
  5557.  
  5558.                 ARexxRunning = FALSE;
  5559.  
  5560.                 if(ARexxQueue . lh_Head -> ln_Succ)
  5561.                 {
  5562.                     struct Node *Node;
  5563.  
  5564.                     if(Node = RemHead(&ARexxQueue))
  5565.                     {
  5566.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5567.  
  5568.                         SendARexxCommand(Node -> ln_Name,FALSE);
  5569.  
  5570.                         FreeVecPooled(Node);
  5571.                     }
  5572.                     else
  5573.                         ReleaseSemaphore(&ARexxQueueSemaphore);
  5574.                 }
  5575.                 else
  5576.                     ReleaseSemaphore(&ARexxQueueSemaphore);
  5577.  
  5578.                 break;
  5579.  
  5580.                 // Call a menu item
  5581.  
  5582.             case DATAMSGTYPE_MENU:
  5583.  
  5584.                 HandleMenuCode((ULONG)Item -> Size,(ULONG)Item -> Data);
  5585.  
  5586.                 break;
  5587.  
  5588.                 // Rendezvous with external process
  5589.  
  5590.             case DATAMSGTYPE_RENDEZVOUS:
  5591.  
  5592.                 if(ReadRequest && WriteRequest)
  5593.                 {
  5594.                         // Abort serial I/O processing
  5595.  
  5596.                     ClearSerial();
  5597.  
  5598.                     BlockWindows();
  5599.  
  5600.                         // Return the message, caution, we're not ready yet
  5601.  
  5602.                     Forbid();
  5603.  
  5604.                     DeleteMsgItem(Item);
  5605.  
  5606.                     Item = NULL;
  5607.  
  5608.                         // Prepare to wait...
  5609.  
  5610.                     ClrSignal(SIG_HANDSHAKE);
  5611.  
  5612.                     Wait(SIG_HANDSHAKE);
  5613.  
  5614.                         // Pick up the queue
  5615.  
  5616.                     RestartSerial();
  5617.  
  5618.                     Permit();
  5619.  
  5620.                     ReleaseWindows();
  5621.                 }
  5622.  
  5623.                 break;
  5624.  
  5625.                 // Discard current buffer contents
  5626.  
  5627.             case DATAMSGTYPE_CLEARBUFFER:
  5628.  
  5629.                 FreeBuffer();
  5630.                 break;
  5631.         }
  5632.  
  5633.         if(Item)
  5634.             DeleteMsgItem(Item);
  5635.  
  5636.         return(TRUE);
  5637.     }
  5638.     else
  5639.         return(FALSE);
  5640. }
  5641.  
  5642.     /* HandleOwnDevUnit():
  5643.      *
  5644.      *    Deal with the OwnDevUnit signal notification.
  5645.      */
  5646.  
  5647. BYTE
  5648. HandleOwnDevUnit()
  5649. {
  5650.     ObtainSemaphore(&OnlineSemaphore);
  5651.  
  5652.     if(!Online || !ReadPort || (Online && Config -> SerialConfig -> ReleaseODUWhenOnline))
  5653.     {
  5654.         ReleaseSemaphore(&OnlineSemaphore);
  5655.  
  5656.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_RELEASE)
  5657.             HandleSerialRelease();
  5658.  
  5659.         if(Config -> SerialConfig -> SatisfyODURequests == ODU_WAIT)
  5660.         {
  5661.             APTR    OldPtr = ThisProcess -> pr_WindowPtr;
  5662.             BYTE    Continue,SerialClosed;
  5663.  
  5664.             ThisProcess -> pr_WindowPtr = (APTR)Window;
  5665.  
  5666.                 /* This might happen if an ARexx user
  5667.                  * released the serial device and
  5668.                  * failed to reopen it.
  5669.                  */
  5670.  
  5671.             if(ReadPort)
  5672.                 SerialClosed = FALSE;
  5673.             else
  5674.                 SerialClosed = TRUE;
  5675.  
  5676.             BlockWindows();
  5677.  
  5678.                 /* Prevent catastrophes! */
  5679.  
  5680.             ObtainSemaphore(&OnlineSemaphore);
  5681.  
  5682.             if(Online && !SerialClosed && !Config -> SerialConfig -> ReleaseODUWhenOnline)
  5683.             {
  5684.                 ReleaseSemaphore(&OnlineSemaphore);
  5685.  
  5686.                 if(!MyEasyRequest(Window,LocaleString(MSG_TERMMAIN_YOU_ARE_STILL_ONLINE_TXT),LocaleString(MSG_GLOBAL_YES_NO_TXT)))
  5687.                     Continue = FALSE;
  5688.                 else
  5689.                     Continue = TRUE;
  5690.             }
  5691.             else
  5692.             {
  5693.                 ReleaseSemaphore(&OnlineSemaphore);
  5694.  
  5695.                 Continue = TRUE;
  5696.             }
  5697.  
  5698.             if(Continue)
  5699.             {
  5700.                 if(!SerialClosed)
  5701.                 {
  5702.                     ClearSerial();
  5703.  
  5704.                     DeleteSerial();
  5705.                 }
  5706.             }
  5707.  
  5708.             ThisProcess -> pr_WindowPtr = OldPtr;
  5709.  
  5710.             ReleaseWindows();
  5711.  
  5712.                 // Start polling for the device to become
  5713.                 // available again
  5714.  
  5715.             PollODU = TRUE;
  5716.         }
  5717.     }
  5718.     else
  5719.         ReleaseSemaphore(&OnlineSemaphore);
  5720.  
  5721.     return(FALSE);
  5722. }
  5723.  
  5724.     /* FullHangup():
  5725.      *
  5726.      *    In a nutshell, do the full work required to hang up the line.
  5727.      */
  5728.  
  5729. VOID __regargs
  5730. FullHangup(BOOL ForceIt)
  5731. {
  5732.     BlockWindows();
  5733.  
  5734.     if(DialMsg)
  5735.     {
  5736.         DialMsg -> rm_Result1 = RC_WARN;
  5737.         DialMsg -> rm_Result2 = 0;
  5738.  
  5739.         ReplyMsg(DialMsg);
  5740.  
  5741.         DialMsg = NULL;
  5742.     }
  5743.  
  5744.     HangUp();
  5745.  
  5746.     ReleaseWindows();
  5747.  
  5748.     if(Config -> SerialConfig -> CheckCarrier && !ForceIt && !Config -> SerialConfig -> DirectConnection)
  5749.         HungUp = TRUE;
  5750.     else
  5751.     {
  5752.         ObtainSemaphore(&OnlineSemaphore);
  5753.  
  5754.         if(Online)
  5755.         {
  5756.                 /* Remember online state. */
  5757.  
  5758.             WasOnline = Online;
  5759.  
  5760.                 /* We are no longer online. */
  5761.  
  5762.             Online = FALSE;
  5763.         }
  5764.  
  5765.         ReleaseSemaphore(&OnlineSemaphore);
  5766.  
  5767.         HandleOnlineCleanup(TRUE);
  5768.     }
  5769. }
  5770.